Help improve Learn WordPress for everyone - fill out the individual learner survey today.

Introduction to theme.json


Introduced in WordPress 5.8, the theme.json file allows block theme developers to control the settings and styles of the blocks in the Editor.

In this tutorial, you will be introduced to the theme.json file, how it works, and how you can control these settings and styles.

Learning outcomes

  1. Learn about the theme.json file, its format, and structure
  2. Control theme functionality through theme.json settings
  3. Create and apply theme styles through theme.json

Comprehension questions

  1. Where does the theme.json file reside in a theme’s directory?
  2. What are the two top-level keys that manage theme settings and styles for a theme?
  3. Where can you find more information about the theme.json file in the WordPress developer documentation?
View Transcript

In this lesson, you’re going to learn about the theme.json file that allows block theme developers to define theme settings, and then apply those settings to the elements of the theme.

Introduced in WordPress 5.8, the theme.json file allows block theme developers to control the settings and styles of the blocks in the editor. With the introduction of blocks into the site editing experience, the number of settings theme developers may need control over has increased. By making these settings available in a specific standard, the theme.json file allows for a central point of configuration, while also providing a more consistent experience when configuring theme settings and styles.

Let’s take a look at the theme json file in a code editor. The theme.json file resides in the root directory of a WordPress theme. It contains a JSON object which is a collection of key value pairs. JSON, which is an abbreviation of JavaScript Object Notation, is a standard text based format for representing structured data based on the JavaScript object syntax. Note that the main JSON object is always wrapped in curly braces, and that each key value pair is separated by a comma. The comma is important and must be included after each key value pair, except for the last one in any given object. If you’re using a good code editor, you’ll notice that leaving out the comma will result in the code editor highlighting an error. In this example, version is the first key with a value of two. The values of the next two keys, settings and styles, are also objects indicated by the curly braces. These are additional collections of key value pairs which also follow the JSON Syntax.

The theme.json file is validated against a schema which provides auto completion in code editors. This means that as you type, the editor will suggest the available options and possible available values for each option. This is a great way to learn about the available options and ensure that you’re using the correct syntax. To enable the schema validation, the schema key and value needs to be added to the top of the file. The schema value can be found in the Block Editor handbook, theme.json Reference Guide, under the Schema header. With this added most modern IDEs and code editors will automatically suggest the available options as you type, and will also provide a description of each option. For example, watch what happens if you create an empty theme.json in Visual Code Studio with just the schema key. As soon as you start a new key by opening the double quotes, a list of available top level keys is suggested. If you select version, it automatically populates the value with two, which is the latest version of theme.json.

By default, WordPress Core ships with a default theme.json, which enables a specific set of settings and creates a set of predefined CSS variables. The settings key is where the theme developer can extend the default theme.json or enable or disable specific theme settings and functionality, as well as configure new CSS variables. These settings can then be applied to the theme globally, or to specific block elements.

Let’s look at one of the first settings that a theme developer can enable appearanceTools, appearanceTools is disabled by default. And this one setting controls all of the following features on blocks that support them. The ability to set border colour, radius, style and width, the ability to set link colour, the ability to set block gap, margin, and padding values, and the ability to set the text line height. By enabling appearanceTools, the theme developer is enabling all of these features.

If you’re editing a theme in the site editor, you can now see these features in the sidebar. So we can set link colour on the header block. We can set border and radius on the featured image for example. And under paragraph we can set things like padding and margin and the link colour.

The ability to enable or disable theme specific settings at a theme json file replaces the requirements to use add_theme_support in a functions.php file. For example, let’s look at the ability to define custom colours for elements in the site editor. By default, if the user wanted to change the colour of something, say the text it is possible to select a custom colour by selecting it from the custom colour picker.

In a classic theme, if a theme developer wants to disable this functionality, they would need to add the following code in their functions.php file, add_theme_support, disable-custom-colours. However, using theme.json, you could do so by setting the settings.colour.custom key to a value of false. Doing so we disable the custom colour picker across all elements in the site editor. If we click on a paragraph, we can select a custom colour. However, you could specifically enable the colour picker for a single block. For example, you could enable the custom colour picker specifically on the paragraph block by adding the following to the paragraph block in the theme.json settings. blocks.core.paragraph, colour.custom and set that to true. Now if you get at the paragraph block, you’ll be able to choose a custom colour.

Text, custom colour picker.

It is also possible to create new CSS preset variables for a theme. CSS variables are defined once but can be used throughout the theme. For example, let’s say you wanted to add a new colour to the colour palette available to WordPress. You could do so by adding a new colour object to the settings.colour.palettes key

Notice how the colour palette key defaults to square braces. This indicates a JavaScript array meaning you can add multiple objects to the colour palette.

To add a colour to the colour palette, give it a name, a hex colour value, and a slug.

This new alternative colour would then be available in the colour palettes in the site editor.

Additionally, users can now use this colour for any element that supports colour. For example, if you wanted to apply this colour to a paragraph blocks text.

With this new colour available to the colour palette of the theme, let’s look at some ways it can be applied to a theme globally, to specific block elements, or to a specific block. By creating this colour, you’ve not only made it available in the site editor, but you’ve also created a new CSS variable for the cover, which can be applied to various elements in the theme. The format for the CSS variable is dash dash WP dash dash preset dash dash color dash dash slug. In this case, the slug is alternative so the CSS variable is –wp–preset–color–alternative. Let’s say you wanted to style all text across the entire theme or site to use the new alternative colour. For this you would use the styles key and set the colour.text key to the new CSS variable

–wp–preset–color–alternative.

If you load this in the site editor you’ll see that all the text across all blocks is now the alternative colour.

Let’s say you want to supply the new colour to a specific block. For example, you wanted to apply the new colour to any instances of the post content block. You could do so by removing the global text colour and adding the colour to the specific block in the styles.blocks key. core.post/content.colour.text and again a CSS variable –wp–preset–color–alternative. Now if you refresh the site editor, you’ll see that the post content block is now the alternative colour. But all other text is the default colour. In WordPress 6.1. It is now also possible to apply predefined CSS variables to certain elements across the theme. For example, let’s say you wanted to apply this colour to the background of all button elements. You can apply this in the theme.json by targeting the styles.elements.button key.

button.colour.background, and again, the CSS variable.

This would apply the colour to any blocks that use the button elements for example, the buttons block or the search block.

This is just a high level overview of what’s possible with theme.json. For more information on how to use it, please see the Global settings and styles guide as well as the theme.json reference in the Block Editor handbook. And also take a look at the theme.json documentation in the Theme handbook.

Happy coding

Introduction

Hey there, and welcome to Learn WordPress.

In this lesson, you’re going learn about the theme.json file that allows block theme developers to define theme settings, and then apply those settings to the elements of the theme.

What is theme.json?

Introduced in WordPress 5.8, the theme.json file allows block theme developers to control the settings and styles of the blocks in the Editor.

With the introduction of blocks into the site editing experience, the number of settings theme developers may need control over has increased.

By making these settings available in a specific standard, the theme.json file allows for a central point of configuration while also providing a more consistent experience when configuring theme settings and styles.

The anatomy of theme.json

Let’s take a look at the theme.json file in a code editor.

The theme.json file resides in the root directory of a WordPress theme. It contains a JSON object, which is a collection of key-value pairs. JSON (an abbreviation of JavaScript Object Notation) is a standard text-based format for representing structured data based on the JavaScript object syntax.

{
  "version": 2,
  "settings": {
  },
  "styles": {
  }
}

Note that the main JSON object is always wrapped in curly braces, and that each key-value pair is separated by a comma. The comma is important, and must be included after each key-value pair, except the last one in any given object.

If you’re using a good code editor, you’ll notice that leaving out a comma will result in the code editor highlighting the error.

In this example, “version” is the first key, with a value of “2”. The values of next two keys, “settings” and “styles”, are also objects (indicated by the curly braces). These are additional collections of key-value pairs, which also follow the JSON syntax.

The theme.json file is validated against a schema, which provides auto-completion in code editors. This means that, as you type, the editor will suggest the available options, and possible available values for each option. This is a great way to learn about the available options, and to ensure that you are using the correct syntax. To enable the schema validation, the “$schema” key and value needs to be added to the top of the file. The schema value can be found in the Block Editor Handbook, Theme.json Reference Guide under the Schema heading.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
  },
  "styles": {
  }
}

With this added, most modern IDE’s will automatically suggest the available options as you type, and will also provide a description of each option. For example, watch what happens if you create an empty theme.json in Visual Code Studio, with just the $schema key.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json"
}

As soon as you start a new key by opening the double quotes, a list of available top level keys is suggested. If you select “version”, it automatically populates the value with “2”, which is the latest version of theme.json

Theme.json settings

By default, WordPress core ships with a default theme.json which enables a specific set of settings, and creates a set of predefined CSS variables.

The “settings” key is where the theme developer can extend the default theme.json to enable or disable specific theme settings and functionality, as well as configure new CSS variables. These settings can then be applied to the theme globally, or to specific block elements.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
  }
}

appearanceTools

Let’s look at one of the first settings than a theme developer can enable, appearanceTools:

appearanceTools is disabled by default, and this one setting controls all the following features on blocks that support them:

  • the ability to set border color, radius, style, and width
  • the ability to set link color
  • the ability to set blockGap, margin and padding
  • the ability to set text lineHeight

By enabling appearanceTools, the theme developer is enabling all of these features.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "appearanceTools": true
  }
}

If you’re editing a theme in the Site Editor, you can now see these features in the sidebar.

  • On the header block you can now set the link color
  • On the featured image you have additional border and radius settings
  • And on a paragraph block you can set the link color, and add padding and margin

Disabling/enabling settings/functionality

The ability to enable or disable theme specific settings in a theme.json file replaces the requirement to use add_theme_support in a functions.php file. Enabling or disabling settings is merely a case of setting a switch from true to false.

For example, let’s look at the ability to define custom colors for elements in the Site Editor.

By default, if a user wanted to change the color of something (say the text), it’s possible to choose a custom color by selecting it from the custom color picker

In a classic theme, if the theme developer wanted to disable this functionality, they would need to add the following code to their functions.php file.

add_action('init', 'setup_theme_functions');
function setup_theme_functions() {
    add_theme_support( 'disable-custom-colors' );
}

However, using theme.json, you could do so by setting the settings.color.custom key to a value of false in the theme.json.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "custom": false
    }
  }
}

Doing so would disable the custom color picker across all elements in the Site Editor.

However, you could specifically enable the color picker for a single block. For example, you could enable the custom color picker specifically on the paragraph block, by adding the following to the paragraph block in the theme.json settings.

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 2,
    "settings": {
        "color": {
            "custom": false
        },
        "blocks": {
            "core/paragraph": {
                "color": {
                    "custom": true
                }
            }
        }
    }
}

Now if you edit a paragraph block, you’ll be able to choose a custom color.

Configuring a new CSS preset

It’s also possible to create new CSS preset variables for a theme. CSS variables are defined once, but can be used throughout the theme.

For example, let’s say you wanted to add a new color to the color palette available to WordPress. You could do so by adding a new color object to the settings.color.palette key.

Notice how the color pallete key defaults to square braces. This indicates a JavaScript array, meaning you can add multiple objects to the colour pallet.

To add a color to the color pallete, give it a name, hex color value, and slug.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Alternative",
          "color": "#135e96",
          "slug": "alternative"
        }
      ]
    }
  }
}

This new Alternative color would then be available in the color palette in the Site Editor.

Additionally, users can now use this color for any element that supports color, for example if you wanted to apply this colour to a paragraph block’s text.

Applying settings

With this new color available to the color palette of the theme, let’s look at some ways that it can be applied to a theme: globally, to specific block elements, or to a specific block.

By creating this new color, you’ve also created a new CSS variable for the color, which can be applied to various elements in the theme. The format for the CSS variable is --wp--preset--color--{slug}. In this case, the slug is alternative, so the CSS variable is --wp--preset--color--alternative.

Applying a setting globally

For example, let’s say you wanted to style all text across the entire theme/site to the new Alternative color:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Alternative",
          "color": "#135e96",
          "slug": "alternative"
        }
      ]
    }
  },
  "styles": {
    "color": {
      "text": "var(--wp--preset--color--alternative)"
    }
  }
}

If you load this in the Site Editor, you’ll see that all the text across all blocks is now the Alternative color.

Applying a setting to a block

Let’s say you wanted to apply the new color to a specific block. For example, let’s say you wanted to apply the new color to any instances of the Post Content block. You could do so by removing the global text color, and adding the color to the specific block in the styles.blocks key.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Alternative",
          "color": "#135e96",
          "slug": "alternative"
        }
      ]
    }
  },
  "styles": {
    "blocks": {
      "core/post-content": {
        "color": {
          "text": "var(--wp--preset--color--alternative)"
        }
      }
    }
  }
}

Now if you refresh the Site Editor, you’ll see that the text in the Post Content block is now Alt Green, but all other text is the default color.

Applying a setting to a block element

Since WordPress 6.1, it is now also possible to apply predefined CSS variables to certain elements across a theme. For example let’s say you wanted to apply this color to the background of all button elements. You could apply this color in the theme.json by targeting the styles.elements.button key.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Alternative",
          "color": "#135e96",
          "slug": "alternative"
        }
      ]
    }
  },
  "styles": {
    "elements": {
      "button": {
        "color": {
          "background": "var(--wp--preset--color--alternative)"
        }
      }
    }
  }
}

This would apply the color to any blocks that use button elements, for example the Buttons block and the Search block.

Summary

This is just a high level overview of what’s possible with theme.json. For more information on how to use it, please see the Global Settings and Styles guide and the theme.json reference in the Block Editor Handbook, as well as the theme.json documentation in the Theme Handbook.

Happy coding!

Workshop Details


Presenters

Jonathan Bossenger
@psykro

WordPress Code Instructor at Automattic, full-time sponsored member of the training team creating educational content for developers on Learn WordPress. Husband and father of two energetic boys.