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:
- Generates CSS Custom Properties (Variables) for colors, fonts, and spacing.
- Generates utility classes.
- Configures the Gutenberg Editor UI (enabling/disabling specific controls).
- 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.