Creating WordPress block themes

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 highlight some differences between classic themes and block themes.

By the end of this first lesson, you will have created an empty WordPress block theme with support for the Site Editor. 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.

For this lesson, you will need your favorite code editor and a WordPress installation to test your theme.

Level: ,

Estimated reading time: 7 minutes

Last updated


The Site Editor will be one of your primary tools for creating WordPress block themes. For most block theme projects, this is where you will assemble and style blocks to create your templates, parts, and patterns.

The Site Editor is a new tool for visual editing of all parts of the website, using blocks.

Workflow for creating block themes

Once you have learned the basics about block themes, your block theme creation flow will probably look something like this:

  1. Install the Create Block Theme plugin
  2. Create a blank theme from the plugin options
  3. Add a color palette and fonts in the Site Editor Styles panel
  4. Create block templates based on the desired design
  5. Export the changes to a theme .zip file
  6. Tweak the theme files in your code editor
  7. Repeat from step 4

There are no right or wrong workflows. With some practice, you will find a workflow that suits you. Eventually, you will have created your own starter theme and you will no longer need to use the plugin to create the initial files. You will also likely have a library of pattern and template designs that you can reuse in your themes.

However, there are several gotchas when creating block themes, especially if you are comparing them to classic themes. That is why I suggest starting with these five lessons, which will help you understand the basics of block themes and give you a good starting point.

You can follow along and create a block theme with me, or use the “super quick start guide” and only have 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 -->
<!-- /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 block themes to include an index.php file. Instead, the minimum required files are style.css and an index.html file. The index.html file must be placed inside a folder called templates.

First, select a theme name and use the slug to create your new theme folder inside
wp-content/themes. If your theme name is “Lesson One”, your folder will be:


Create a style.css file in the root folder of the theme. Block 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.4. 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

Your theme will rely on block styles and the theme.json configuration file as much as possible.
I suggest starting with an empty style.css file, 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

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 unnecessary: WordPress handles the width limitations by setting a max-width on the blocks using CSS.

Tip! 840px gives your website many characters per line, making it difficult to read. Adjust the width to a comfortable reading length depending on your selected font family and size.

Your theme structure should now look like this:


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 image sizes, or use hooks.

Create a new file in the root folder and name it functions.php.
Next, add the file header, and if you like, enqueue the style.css file for later use with wp_enqueue_style():

 * Functions and definitions
 * @link
 * @package Lesson One
 * @since 1.0.0

 * Enqueue the style.css file.
 * @since 1.0.0
function lesson_one_style() {
		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 that some blocks use. 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 and now considered legacy, my recommendation is not to include it, but I will provide an example of how to add it:

if ( ! function_exists( 'lesson_one_setup' ) ) {
function lesson_one_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 head 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(); ?>>
	<meta charset="<?php bloginfo( 'charset' ); ?>" />
	<?php wp_head(); ?>

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>


<?php wp_footer(); ?>

If you need to change 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.

<div class="wp-site-blocks">

This is added by the private function get_the_block_template_html().