This lesson is the first in a series of exercises to learn how to create block themes, also known as full site editing themes. You will learn about the minimum file requirements, theme setup, and file structure. I will also point out some important differences between classic themes and block themes.
By the end of this first lesson, you will have created an empty WordPress theme with support for full site editing. You will continue to build upon this theme over the next lessons:
- In lesson two you will learn about the block markup that you will use in the theme templates.
- In lesson three you will add functional templates such as single posts, pages, and archives.
- In lesson four you will learn about the theme.json configuration file
- In lesson five you will add settings and styles to theme.json.
- Lesson six is in the writing stages and will guide you through how to continue building the theme in the Site Editor.
For this lesson, you will need your favorite code editor and a WordPress installation to test your theme on.
Estimated reading time: 6 minutes
Last updated
Introduction
The new Site Editor (Added in WordPress 5.9) will be one of your primary tools for creating WordPress block themes. For most block theme projects, that is where you will assemble, style, and edit blocks:

But the Site Editor will not expose all settings. Knowing how to make manual edits to the theme files is perhaps not as exciting, but it is good basic knowledge.
You need to install and activate a block theme before you can use the Site Editor. That is why the first two lessons in this chapter will be about manually creating a theme.
You can follow along and create a block theme with me, or use the “super quick start guide” and only use this page as a reference.
Super quick start guide for eager theme developers
1. Create a new theme folder inside wp-content/themes
.
2. Create a style.css file for your new theme.
3. Create two new folders inside the theme folder: templates
and parts
.
4. Inside the parts
folder, create an HTML file called header.html
.
5. In header.html
, add the following code: <!-- wp:site-title /-->
and save.
6. Inside the templates
folder, create an HTML file called index.html
.
7. In index.html
, add the block code below, and save:
<!-- wp:template-part {"slug":"header"} /-->
<!-- wp:query {"queryId":0,"query":{"perPage":3,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true,"taxQuery":null,"parents":[]},"displayLayout":{"type":"list"}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title /-->
<!-- wp:post-date /-->
<!-- wp:post-content /-->
<!-- /wp:post-template -->
</div>
<!-- /wp:query -->
8: Activate the theme.
Step 1: Create the theme folder and style.css
You can expect that the theme setup will be more straightforward and require fewer files in the future. It is even possible that the only file you will need is the new theme.json
configuration file. But let’s look at the theme file structure and block templates required to create block themes today.
Minimum requirements
Since version 6.0, WordPress no longer requires full site editing themes to include an index.php
file. Instead, the minimum required files are style.css
and an index.html
file placed inside a folder called templates
.
First, select a theme name and use the slug to create your new theme folder insidewp-content/themes
. If your theme name is “Lesson One”, your folder will be:
wp-content/themes/lesson-one
Create a style.css
file in the root folder of the theme.
Full site editing themes use a standard style.css file header.
Copy and paste the following code into the file. Update the fields as needed.
The only required part of the file header is the theme name.
/*
Theme Name: Name of the theme.
Author: The name of the individual or organization who developed the theme.
Description: A short description of the theme.
Version: The version, written in X.X or X.X.X format.
Requires at least: The oldest main WordPress version supported, written in X.X format.
Tested up to: The last main WordPress version the theme has been tested up to, i.e. 6.0. Write only the number.
Requires PHP: The oldest PHP version supported, in X.X format, only the number.
License: The license of the theme.
License URI: The URL of the theme license.
Text Domain: The string used for textdomain for translation. The theme slug.
*/
Start with an empty style.css file
Our theme will rely on block styles and the theme.json
configuration file as much as possible.
I suggest starting with an empty style.css
, except for the file header.
Using an empty style.css
file is an excellent way to learn the strengths and limitations of theme.json
.
Step 2: Add your first block template
Block templates are your base HTML files and just like PHP files in classic themes, they follow the WordPress template hierarchy.
/templates/index.html
is the equivalent of index.php
in a classic theme./templates/404.html
is the equivalent of 404.php
and so on.
For Gutenberg and WordPress to recognize that the active theme has support for the site editor, the theme must include an index.html
file, and you must place it inside a folder called templates
.
– Go ahead and create the folder and the empty index file before continuing to the next step. You will add content to this file in lesson three.
The template hierarchy -refresher
The following default, top-level templates are supported in the WordPress template hierarchy:
- index
- 404
- archive
- author
- category
- tag
- taxonomy
- date
- embed
- home
- front-page
- privacy-policy
- page
- search
- single
- singular
- attachment
https://developer.wordpress.org/themes/basics/template-hierarchy/
Step 3: Create the theme.json configuration file
Theme.json
is a configuration file for enabling and disabling block settings and for applying styles to blocks. I will describe how to use theme.json
in detail in upcoming lessons, so do not worry if you are not familiar with this format yet.
In this lesson, you will add the layout setting: Block themes use this setting to specify the default content width and to support wide width, full width, left, center, and right alignments.
Create the theme.json
file in the root folder, and copy and paste the following code:
{
"version": 2,
"settings": {
"layout": {
"contentSize": "840px",
"wideSize": "1100px"
}
}
}
You have now set the content width to 840px and the wide width to 1100px.
These two values match the default widths in the editors, but you can adjust them.
— There is no setting for full width because it is not needed: WordPress handles the width limitations by setting a max-width
on the blocks using CSS.
Tip! 840px gives your website a high number of characters per line which can be difficult to read. Adjust the width to a comfortable reading length depending on your selected font family and font size.
Your theme structure should now look like this:
templates/
index.html
style.css
theme.json
Step 4: Include functions.php and theme support (optional)
Themes do not require a functions.php
file to work. You can include functions.php
in your block theme if you need to enqueue stylesheets or JavaScript, add custom block styles and custom image sizes, or use hooks.
Create a new file in the root folder and name it functions.php
.
Add the file header, and if you like, enqueue the style.css
file for later use with wp_enqueue_style()
:
<?php
/**
* Functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package Lesson One
* @since 1.0.0
*/
/**
* Enqueue the style.css file.
*
* @since 1.0.0
*/
function lesson_one_style() {
wp_enqueue_style(
'lesson-one-style',
get_stylesheet_uri(),
array(),
wp_get_theme()->get( 'Version' )
);
}
add_action( 'wp_enqueue_scripts', 'lesson_one_style' );
You do not need to enqueue the comment-reply script commonly used in classic themes, because the comments block enqueues this automatically.
Theme support
The following theme support is automatically enabled for block themes:
post-thumbnails, editor-styles, responsive-embeds, automatic-feed-links, html5 styles, and html5 scripts.
You do not need to include add_theme_support( 'title-tag' )
in the setup function, because WordPress already renders the title tag for full site editing themes.
Similarly, you do not need to register widget areas and menus and add theme support for a custom logo, custom header, or colors.
Adding theme support for wp-block-styles
is optional. This file includes the combined CSS from the theme.scss
file for individual blocks. For example, the padding when you add a background color to a group block and the default border of the quote block. Because this CSS is so opinionated, my recommendation is to not include it, but I will proved an example of how to add it:
if ( ! function_exists( 'lesson_one_setup' ) ) {
function fse_setup() {
add_theme_support( 'wp-block-styles' );
}
}
add_action( 'after_setup_theme', 'lesson_one_setup' );
Templates are loaded in the body element
Templates and template parts use block markup and not plain HTML. One thing I get asked about frequently is how to make updates to the meta tags in the header of the theme.
When you create the templates in the next few lessons, you will find that the header template part does not include a <!DOCTYPE>
,<html>
, or <head>
. There is also no <body>
element.
WordPress already adds the necessary HTML elements and hooks. The complete code is:
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
(template)
<?php wp_footer(); ?>
</body>
</html>
If you need to make changes to the meta tags, you need to use hooks and filters.
On the front, your templates and all your blocks are loaded in the <body>
element, inside a <div>
with the class wp-site-blocks
. There is no way to remove this div.
<body>
<div class="wp-site-blocks">
...
</div>
</body>
This is added by the private function get_the_block_template_html().
Resources
If you want to learn more about the difference between a classic PHP based theme and block themes, there is an excellent section about this in the theme developer handbook, that includes a comparison table: