iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

theme.json

theme.json is the design source of truth for WordPress block themes. Tokens, settings, styles, and the patterns that keep the editor clean.

WordPress — theme.json

EXAMPLE
// ===== Why theme.json =====
// In block themes, theme.json centralises:
//   - Design tokens (colours, fonts, spacing, layout)
//   - Editor settings (what is allowed)
//   - Global styles (block-level defaults)
// It generates CSS custom properties + inline editor UI.

// ===== Minimal theme.json =====
{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "layout": { "contentSize": "720px", "wideSize": "1200px" },
    "color": {
      "palette": [
        { "slug": "primary",    "color": "#2563eb", "name": "Primary" },
        { "slug": "foreground", "color": "#0f172a", "name": "Foreground" },
        { "slug": "background", "color": "#ffffff", "name": "Background" }
      ],
      "custom": false,
      "customGradient": false,
      "defaultPalette": false
    },
    "typography": {
      "fluid": true,
      "fontFamilies": [
        {
          "slug": "sans", "name": "Sans",
          "fontFamily": "Inter, system-ui, sans-serif"
        }
      ],
      "fontSizes": [
        { "slug": "sm",  "size": "14px", "name": "Small" },
        { "slug": "md",  "size": "16px", "name": "Medium" },
        { "slug": "lg",  "size": "20px", "name": "Large" },
        { "slug": "xl",  "size": "32px", "name": "X-Large" }
      ]
    },
    "spacing": {
      "units": ["px", "rem", "em"],
      "spacingScale": { "steps": 8 }
    }
  },
  "styles": {
    "color": {
      "background": "var(--wp--preset--color--background)",
      "text": "var(--wp--preset--color--foreground)"
    },
    "typography": {
      "fontFamily": "var(--wp--preset--font-family--sans)",
      "fontSize": "var(--wp--preset--font-size--md)"
    },
    "elements": {
      "link": { "color": { "text": "var(--wp--preset--color--primary)" } },
      "h1": { "typography": { "fontSize": "var(--wp--preset--font-size--xl)" } }
    },
    "blocks": {
      "core/button": {
        "color": {
          "background": "var(--wp--preset--color--primary)",
          "text": "var(--wp--preset--color--background)"
        }
      }
    }
  }
}

// ===== Generated CSS custom properties =====
// --wp--preset--color--primary: #2563eb;
// --wp--preset--font-size--md: 16px;
// Use these anywhere in templates / parts.

// ===== Disabling features =====
// settings.color.custom = false  -> remove the colour picker in editor
// settings.typography.fontSizes (with no slugs) -> remove default sizes
// settings.spacing.units -> restrict allowed units

// Discipline: lock the design system inside theme.json so editors can't drift.

// ===== Per-block overrides =====
// styles.blocks['core/heading'].typography.fontWeight = '700'
// Applies to that block specifically, not globally.

// ===== Patterns (template parts can reference tokens) =====
// patterns/cta.php:
// register_block_pattern( 'mytheme/cta', [
//     'title' => __( 'Call to action', 'mytheme' ),
//     'content' => '<!-- wp:button { "backgroundColor": "primary" } --><div class="wp-block-button"><a class="wp-block-button__link wp-element-button has-primary-background-color has-background">Sign up</a></div><!-- /wp:button -->',
// ] );

// ===== When theme.json wins =====
// - Block themes (FSE)
// - Strict brand guidelines you want editors to follow
// - Consistent design across multiple block patterns
// - Avoiding stylesheet drift

// ===== Pitfalls =====
// - Mixing custom CSS that overrides theme.json -> drift between editor + frontend
// - Not pinning '$schema' URL — schema validators help during edit
// - Overriding core blocks via styles.blocks AND functions.php register_block_style -> precedence confusion
// - Removing default colour palette without providing one -> empty colour picker

Why it matters

theme.json is the design contract for block themes. Define palette, typography, spacing once; the editor + the frontend consume the same tokens. Lock down customisation flags to prevent drift and reference CSS custom properties in templates. Less stylesheet, more system.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
{
    "version": 2,
    "settings": {
        "color": { "palette": [{ "slug": "brand", "color": "#04AA6D", "name": "Brand" }] }
    }
}
Try it Yourself »

Discussion

Loading…