Registering Custom Post Types for FSE (The Right Way)
While there are many plugins (like CPT UI) to generate Custom Post Types, creating them manually in functions.php gives you version-controllable code and cleaner setups.
For Full Site Editing (FSE), there are specific arguments you must include to ensure the Block Editor works and that you can create templates for this post type in the Site Editor.
1. The Basic Registration Code
Add this function to your theme's functions.php or a custom functionality plugin.
function my_register_portfolio_cpt() {
$labels = array(
'name' => _x( 'Projects', 'Post Type General Name', 'my-textdomain' ),
'singular_name' => _x( 'Project', 'Post Type Singular Name', 'my-textdomain' ),
'menu_name' => __( 'Projects', 'my-textdomain' ),
'all_items' => __( 'All Projects', 'my-textdomain' ),
'add_new_item' => __( 'Add New Project', 'my-textdomain' ),
'edit_item' => __( 'Edit Project', 'my-textdomain' ),
'view_item' => __( 'View Project', 'my-textdomain' ),
);
$args = array(
'label' => __( 'Project', 'my-textdomain' ),
'labels' => $labels,
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
'taxonomies' => array( 'category', 'post_tag' ), // Optional: Share WP categories
'hierarchical' => false, // False = Posts (Time based), True = Pages (Parent/Child)
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-art', // https://developer.wordpress.org/resource/dashicons/
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true, // Crucial for FSE Archive Templates
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => true, // CRITICAL FOR FSE / GUTENBERG
);
register_post_type( 'portfolio', $args );
}
add_action( 'init', 'my_register_portfolio_cpt', 0 );
2. Key FSE Arguments Explained
show_in_rest => true
Mandatory. This enables the REST API. Without this:
- The Block Editor (Gutenberg) will not load. You will be stuck with the Classic Editor.
- The FSE Site Editor cannot see the post type.
has_archive => true
This enables the archive slug (e.g., example.com/portfolio/).
- FSE Impact: If set to
true, you can create anarchive-portfolio.htmltemplate in the Site Editor to design the project grid.
supports
Defines what panels appear in the editor.
'editor': The content area (Block Editor).'thumbnail': The "Featured Image" panel. Required if you want to use the "Post Featured Image" block in your templates.'excerpt': The "Excerpt" panel. Required for the "Post Excerpt" block.
3. Creating Templates in FSE
Once registered, go to Appearance > Editor > Templates. You will likely see options to create:
- Single Item: Project (Renders
single-portfolio.html) - Archive: Projects (Renders
archive-portfolio.html)
If you don't see them, ensure public, show_ui, and show_in_rest are all true.
4. Flushing Rewrite Rules (The 404 Fix)
After adding a new CPT, visiting its URL often results in a 404 error because WordPress hasn't updated its permalink database.
The Fix:
- Go to Settings > Permalinks.
- Click Save Changes (you don't need to change anything).
- This flushes the rewrite rules and fixes the 404s.