Creating block-based WordPress themes

This is the first lesson in a series of exercises where you will learn how to create block themes.
In this lesson you will learn about the minimum file requirements and theme setup.

Level: Beginner, developer

For this full site editing lesson you will need:

  • A WordPress installation with some test content and the Gutenberg plugin.
  • Your favorite code editor

Estimated reading time: 6 minutes

This lesson was updated on July 21 2021.

Once the site editor is completed, the editor will be your primary tool for creating block-based WordPress themes. That is where you will assemble, style, and edit blocks.
But the 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.

Before you can use the site editor to create new block templates, a block theme needs to be installed and activated. That is why the first lesson in this section will be about manually creating a basic theme that you can build upon.

You can follow along and create your first block theme together with me,
or you can use the “super quick start guide” and only use this page as a reference.

Super quick start guide for eager theme developers

First, you must enable Gutenberg.

1. Create a new theme folder inside wp-content/themes.
2. Create a style.css file for your new theme.
3. Create a functions.php file.
4. Create a blank index.php file.
5. Create two new folders inside the theme folder: block-templates and
6. Inside the block-template-parts folder, create an HTML file called header.html.
7. In header.html, add the following code: <!-- wp:site-title /--> and save.
8. Inside the block-templates folder, create an HTML file called index.html.
9. In index.html, add the block code below, and save:

<!-- wp:template-part {"slug":"header"} /-->
<!-- wp:query -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title /-->
<!-- wp:post-date /-->
<!-- wp:post-content /-->
<!-- /wp:post-template -->
<!-- /wp:query -->

10: Activate the theme.

Theme setup today and in the future

You can expect that in the future, the theme setup will be simpler and require fewer files.
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 that are needed for creating a block-based theme today.

Minimum requirements

First, select a name for your theme and use the theme slug to create your theme folder.
If your theme name is “FSE”, short for full site editing, then your theme folder will be:


These first two files are required for any theme to be activated:

Create a new blank file in the root folder and name it index.php.
Without index.php, the WordPress installation will consider the theme broken.

Create a style.css file inside the root folder.
The file header provides the WordPress installation with information about the theme.
Full site editing themes use a standard style.css file header:

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. 5.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.

What about the styles? Our theme will rely on the block styles as much as possible.
But sometimes that is not enough, and if you want to include a CSS reset you need to enqueue that separately or add it in style.css.

I am going to add a minimal amount of styles for now. Copy this into the style.css file:

body {
	overflow-x: hidden;

* {
	box-sizing: border-box;

/* Elements */
img {
	max-width: 100%;
	height: auto;

Themes do not require functions.php to work. But you can use it to cover things that full site editing can not do yet.
Include this file if you need to: Enqueue styles, JavaScript or fonts, create block patterns, or use hooks that are not available for blocks.

Create a new file in the root folder and name it functions.php.
Add the file header and enqueue the style.css file:

 * Functions and definitions
 * @link
 * @package FSE
 * @since 1.0.0

 * Enqueue the style.css file.
 * @since 1.0.0
function fse_styles() {
		wp_get_theme()->get( 'Version' )
add_action( 'wp_enqueue_scripts', 'fse_styles' );

I am choosing not to enqueue the comment-reply script. This is because the comments block enqueues this automatically from version 10 of Gutenberg.

Theme support

Our theme will have a setup function for adding theme support, but it will have fewer items
than you might see in a classic PHP based theme.

  • add_theme_support( 'automatic-feed-links' );
  • add_theme_support( 'responsive-embeds' );
  • add_theme_support( 'editor-styles' ); -If you are using editor styles.
  • add_theme_support( 'wp-block-styles' );

I have not used add_theme_support( 'title-tag' ); because it is already included with full site editing.

When you create block themes the featured image is a block, so you do not have to add theme support for post thumbnails.
If you want to add specific image sizes or set the post thumbnail size, you can still do that in the setup function.

Similarly, you do not need to register widget areas, menus, add support for a custom logo, custom header, or colors.

if ( ! function_exists( 'fse_setup' ) ) {
	function fse_setup() {
            add_theme_support( 'automatic-feed-links' );
            add_theme_support( 'responsive-embeds' );
            add_theme_support( 'editor-styles' ); // Only if you are using editor styles.
            add_theme_support( 'wp-block-styles' );
add_action( 'after_setup_theme', 'fse_setup' );

Later you will add support for wide and full-width blocks and features like the color palette, gradients, and font sizes via the theme.json file.

Block templates

For Gutenberg and WordPress to recognize that the active theme has support for full site editing, the theme must include an index.html file and it must be placed inside a folder called block-templates.

Block templates are your base files. They are HTML files and you place them inside a folder called block-templates.
Block templates follow the WordPress template hierarchy:
/block-templates/index.html is the equivalent of index.php in a classic theme.
/block-templates/404.html is the equivalent of 404.php, and so on.

Block template parts

Block template parts are not required, but they help theme authors structure the theme with reusable, smaller parts.
A template part is a block that is a container for other blocks. They are HTML files and you place them inside a folder called block-template-parts.
/block-template-parts/header.html would be the equivalent of header.php.

The template hierarchy -refresher

The following default templates are supported in the WordPress template hierarchy:
and attachment.

Inside the theme folder, create the two new folders: block-templates and block-template-parts.
Your theme structure should now look like this:


You can download the empty theme from GitHub.

Templates are loaded in the body element

Templates and template parts uses block markup and not plain HTML. When you create the templates in the next lesson, you will find that the header template part does not include a <!DOCTYPE>,<html>, or <head>. There is also no <body> element.

Gutenberg already adds the necessary HTML elements and WordPress hooks. The full 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(); ?>


On the front, templates are loaded in the <body> inside a <div> with the class “wp-site-blocks”:

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

You will continue creating your block templates with the exercise in the next lesson.