FSE Template Hierarchy: Templates vs. Parts
In Classic themes, the Template Hierarchy relied on PHP files like single.php or archive.php. In FSE Block Themes, this logic remains largely the same, but the implementation has moved to HTML files containing block markup.
1. The Directory Structure
A standard block theme has two critical directories for structure:
templates/: Full-page layouts. These correspond to WordPress hierarchy logic (e.g.,index.html,404.html,single.html).parts/: Reusable sections included inside templates (e.g.,header.html,footer.html,sidebar.html).
The "Why": Modularity
Separating Parts from Templates allows you to update a Header in one place (parts/header.html) and have it reflect across every Template that includes it.
2. The templates/ Directory
These files dictate the layout for entire pages. WordPress automatically picks the correct file based on the URL.
index.html: The fallback for everything. Required.single.html: Used for single blog posts.page.html: Used for static pages.archive.html: Used for category/tag lists.404.html: Used for when content is not found.
Example templates/index.html:
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main"} -->
<!-- wp:query {"queryId":0,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} -->
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-excerpt /-->
<!-- /wp:post-template -->
<!-- /wp:query -->
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->
3. The parts/ Directory
Template Parts are "dumb" containers. They don't know about the URL or the Query. They just hold blocks.
Referencing a part:
To load parts/header.html, you use the Template Part block in your template:
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
- slug: Matches the filename (minus
.html). - tagName: The HTML wrapper tag (e.g.,
<header>,<footer>,<div>).
4. Custom Templates
Sometimes you want a specific layout for a specific page (e.g., "Landing Page - No Header"). You can create a custom template file (e.g., templates/landing-page.html), but WordPress won't show it in the Page Editor dropdown unless you register it in theme.json.
Registering in theme.json:
{
"customTemplates": [
{
"name": "landing-page",
"title": "Landing Page (No Header)",
"postTypes": ["page"]
}
]
}
File Mapping:
name: "landing-page"-->templates/landing-page.html
5. Next Steps
Templates are static without dynamic content. The engine that powers the content grid inside these templates is the Query Loop.
Proceed to Part 6: The Query Loop.