FSE: Set the Default Template for Your Custom Post Type

If you are using a block theme–one that uses full site editing (FSE)–and want to create a default template for your custom post type, this article can help. Relevant information for the newer FSE themes, such as Twenty Twenty-Three, is hard to find. I want to spare you the frustration I had weeding out obsolete information to find the solution I needed.


    How to Create a Custom Post Type

    For creating the custom post type, I recommend the Custom Post Type UI plugin. If you don’t wish to keep another plugin running on your site, you can install it long enough to create your custom post type, copy the PHP code it can generate for you, and insert that into your child theme’s functions.php file. At that point, you can uninstall the plugin if you wish. Even if you already know how to write that PHP code, the plugin will save you a good deal of time.

    If you get stuck, you will find a lot of help online. One good starting point is the article at wpbeginner, “How to Create Custom Post Types in WordPress.” Rather than duplicating information that is readily available, I am not giving further instructions here.

    How to Create a Custom Template

    You can create a custom template using the full site editor or by creating your own file with the .html extension and placing it inside the templates folder of your child theme (or custom parent theme if you are the maintainer of that theme).

    The best approach is usually to create the template with the full site editor and then copy the code to an HTML file. You can also copy an existing template file that is similar to what you want, give it a new name, and then modify that either directly or through the full site editor. Be warned, though: If you made changes to a template using the full site editor, those changes are stored in the WordPress database, not in the HTML template file. The template file contains the original template before you changed it (unless you previously exported your changes to an HTML file that you then used).

    Steps to create a template using the full site editor:

    1. Choose from the admin menu, Appearance -> Editor.
    2. Click on “Templates“.
    3. Click on the “+” (plus sign).
    4. Click “Custom Template“.
    5. Enter a user-friendly name for you template and click “Create“. (This name is neither a slug nor a file name, so spaces in the name are fine.)
    6. Create your template with the blocks you will want to appear each time someone uses the template. Be sure to include template parts blocks for “Header” and a “Footer” if you want your custom post type template to show the same header and footer that the rest of your site shows. Another block you will usually want is “Post Title” so that you will have a separate field for entering the title, just like you get on regular post and page editing screens. Almost certainly you will also want the “Post Content” block (unless your custom post type only allows the display of custom fields).
    1. When you are finished, do not click the “Save” button at the upper right of the screen. If you do, it is OK, but you will need to remove your template from the full site editor later. Instead, click the three vertical dots in the upper right of the screen.
    1. Click on “Code editor“. The code you then see, which WordPress uses to figure out what to show on your page, will look something like the following, but probably with more lines, depending upon how many blocks you added to your template. For example, your code will probably include a line representing the footer and perhaps a sidebar with various blocks within that.
    <!-- wp:template-part {"slug":"header","theme":"twentytwentythreechild"} /-->
    <!-- wp:post-title /-->
    <!-- wp:post-content /-->
    1. Copy the code you see and paste it into a blank file. Save the file. If the template acts like a WordPress blog post, save it with the name “single-yourtemplatename.html“, where “yourtemplatename” should be replaced by a name that matches your custom post type, e.g., “single-participants.html” for a custom post type named “participants”. If the template is for a static page type, as the “About” and “Contact” pages usually are, use “page-yourtemplatename.html” instead. If the template is meant to display a particular category of post types, use “category-yourtemplatename.html.”
    2. Upload that file to the “templates” folder of your child theme.

    For more information, see A Developers Guide to Block Themes, particularly the article, Exporting Custom Templates and Template Parts.

    How to Make Your Template the Default

    I created a custom post type, “Participants” and the HTML template to go with it (single-participants.html), only to be frustrated because the default blog template, single.html, continued to be the default when I added a new “Participant” type of custom post. Simply naming the template single-participants.html made the template available in the editor, but it was not the default template. I could change the custom post type manually to use my template, but this was not acceptable. We would ultimately be giving end-users the ability to create their own “Participant” pages to describe their own organizations, and we needed the template to be our custom one, always and by default.

    To get the custom template as the default for my custom post type, I modified two files, both in the root of my child template: theme.json and functions.php.

    Code for the theme.json File

    The code below designates which post type my template goes with. At the same time, it tells WordPress that this is the default template. However, I also needed to register the same custom template in my functions.php file before the template would actually appear as the default for my post type.

    	"postTypeTemplates": {
    		"participants": {
    		  "defaultTemplate": "single-participants"

    Of course, you will need to replace “participants” with your custom post type slug (the same one you entered using the fields in the Custom Post Type UI, if you used that plugin) and replace “single-participants” with the name of your custom post type template.

    Please back up your original file first. Pay extra attention to where the quotation marks, brackets and comma go. If any of these are missing or in the wrong place, WordPress won’t be able to use the theme.json file and your site will suddenly look terrible, if it comes up at all.

    Although the exact placement of this code within the file does not matter–as long as it is between the outermost opening and closing { } (curly) brackets and not between any other brackets–I recommend inserting the code just after the ending [ ] (square) bracket and , (comma) for the “customTemplates:” section. If you cannot find that section, just insert it after or whatever line has "version": followed by a version number (e.g., "version": 2,). Either location will be easy to find again in the future.

    Code for the functions.php File

    If you do not have a functions.php file in your child theme, create a file of that name in the root of your child theme folder, and on the very first line, type:


    Whether you already had the functions.php file or not, now add this code to it:

    add_filter( 'default_template_types', 'add_to_template_types' );
    function add_to_template_types( $template_types ) {
    	$template_types['single-participants'] = array(
            'title'       => 'Participant',
            'description' => 'Displays a page to show Participant info.',
        return $template_types;

    Note that the second parameter of the call to the add_filter function can be any name you wish, but it must match the name of the function below it; otherwise you will get a “function not found” error.


    As I understand it, the PHP code above explicitly sets single-participants as an available template. Although adding the template as an HTML file to the “templates” folder seems to do the same thing, that was not enough. The code we added to the theme.json file to set our custom template as the default for our custom post type only works when we have added the PHP code above to functions.php as well.

    I hope this has been helpful. If you are so moved, leave a comment below.

    By the way, if you need custom WordPress development or would like a consulting session, contact me or fill out a work request form.

    Leave a Comment