Skip to content
wp-skills
Register
tools/wordpress-theme-json-generator

theme.json Generator

Build a block theme's theme.json: colour, typography and spacing presets, layout widths, the styles applied to the page and to links, buttons and headings, and per-block overrides — with the preset slugs already in the form WordPress will turn them into CSS variables.

Editor autocompletion only — WordPress never reads this key, and a nonsense URL produces identical CSS. Pin it to a version like https://schemas.wp.org/wp/6.7/theme.json for that version's completions. Leave it empty to omit the key. version is always emitted as 3.

One key that turns on eighteen settings: every border control, colour for links, margin, padding and block gap, line height, text columns, the dimensions group and sticky position. While it is on, the switches it covers are disabled here and left out of the file — repeating them would say nothing.

Lets a full-width block escape the root padding instead of being inset by it.

Colour

Palette2
  • #1
  • #2

A slug becomes --wp--preset--color--<slug>, but not always as typed: WordPress kebab-cases it, splitting letters from digits too, so brand2 becomes brand-2. Slugs are normalised here to the form WordPress will use, so what you read is what you can reference. Reusing one of core’s twelve slugs — black, white, vivid-red and the rest — does nothing at all unless the default palette below is turned off.

Gradients0

    Off removes core's twelve from the picker and lets a theme colour with the same slug win.

    Off restricts editors to the palette.

    Typography

    Font families1
    • #1
    Font sizes0

      Core ships small, medium, large and x-large. Off is what lets a theme size reuse one of those slugs.

      Turns every font size into a clamp() that scales with the viewport.

      Spacing

      Spacing sizes0

        Core’s own seven sizes are slugged 20 through 80, so a numeric slug collides with them. There is no control here for spacingScale deliberately: it only ever generates those same slugs, which means a theme scale changes nothing unless the switch below is off.

        Units offered in the editor

        Individual controls

        appearanceTools already turns all of these on, so they are left out of the file.

        Styles

        Everything above declares what the editor offers. This is what the site actually looks like — it becomes real CSS rules rather than custom properties. Reference a preset with var(--wp--preset--color--brand).

        Left and right only — vertical root padding pushes the header off the top of the page, and root-padding-aware alignments only compensate horizontally.

        Links

        Emitted as :root :where(a:where(:not(.wp-element-button))), so it styles links without catching a button block.

        Buttons

        Headings

        elements.heading covers h1 through h6 at once.

        Per-block overrides

        A palette entry under a block is scoped to that block: settings.blocks for core/button emits its custom property inside .wp-block-button .wp-block-button__link and nowhere else. The matching .has-…-color utility class is still emitted globally, which is core’s behaviour rather than a choice made here.

        Block colours0
          Block font sizes0
            Block styles0
              theme.json
              {
              	"$schema": "https://schemas.wp.org/trunk/theme.json",
              	"version": 3,
              	"settings": {
              		"appearanceTools": true,
              		"useRootPaddingAwareAlignments": true,
              		"color": {
              			"palette": [
              				{
              					"name": "Brand",
              					"slug": "brand",
              					"color": "#1e1e1e"
              				},
              				{
              					"name": "Surface",
              					"slug": "surface",
              					"color": "#ffffff"
              				}
              			]
              		},
              		"layout": {
              			"contentSize": "660px",
              			"wideSize": "1200px"
              		},
              		"spacing": {
              			"units": [
              				"px",
              				"em",
              				"rem",
              				"%"
              			]
              		},
              		"typography": {
              			"fluid": true,
              			"fontFamilies": [
              				{
              					"name": "Body",
              					"slug": "body",
              					"fontFamily": "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif"
              				}
              			]
              		}
              	}
              }