2 min read

Foundations: Understanding the Theme.json Schema

In the era of Full Site Editing (FSE), theme.json is the brain of your WordPress theme. It replaces the traditional add_theme_support() calls in functions.php and the massive style.css file with a structured configuration file.

1. The "Why": Architecture

Before FSE, themes were a mix of PHP logic and CSS files. Now, WordPress acts as a compilation engine. It reads your theme.json and automatically:

  1. Generates CSS Custom Properties (Variables) for colors, fonts, and spacing.
  2. Generates utility classes.
  3. Configures the Gutenberg Editor UI (enabling/disabling specific controls).
  4. Outputs the CSS for the front end.

2. The Structure: Settings vs. Styles

The most important concept to grasp is the separation between Settings and Styles.

Section Purpose Analogy
Settings Configuration. Defines the palette of options available to the user and the editor. It does not output CSS directly (mostly). The Painter's Palette (List of available colors and brushes).
Styles Implementation. Applies the options defined in Settings to actual HTML elements or blocks. The Painting (Applying the Red color to the Canvas).

The Skeleton

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 3,
    "settings": {
        "appearanceTools": true,
        "color": {
            "palette": []
        },
        "typography": {
            "fontFamilies": []
        }
    },
    "styles": {
        "typography": {
            "fontSize": "1.1rem"
        },
        "elements": {
            "h1": { "color": { "text": "var(--wp--preset--color--primary)" } }
        }
    }
}

3. Schema Versioning

Always specify the schema version.

  • Version 2: Standard for WordPress 5.9+.
  • Version 3: Introduced in WordPress 6.6. It fixes specificity issues and allows for better overriding of styles. Use Version 3 for new projects.

Pro Tip: Include the $schema key at the top. This enables autocomplete and validation in code editors like VS Code.

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

4. The Magic Switch: appearanceTools

In early FSE versions, you had to manually enable every single UI control (border, spacing, lineHeight, etc.). Now, you just use appearanceTools.

/* The New Way */
"settings": {
    "appearanceTools": true
}

What this does: It automatically opts-in to standard design tools like border radius, margin, padding, line height, and link color controls in the editor UI for blocks that support them. It effectively replaces dozens of lines of boolean flags.

5. Next Steps

Now that the structural foundation is laid, the next step is populating the Settings to generate your CSS variables (Presets). This is where the syntax gets tricky with sanitization.

Proceed to Part 2: The Preset Engine.