Block Theme Generator

A working block theme as files: style.css, theme.json with your presets, templates, header and footer parts, and the functions.php WordPress needs.

Enable JavaScript to change the fields; the files below are for the defaults.

What the Themes screen shows.

Also the text domain. Left empty it is the theme name, slugged.

The tags WordPress.org filters themes by. Comma separated.

Hex only. The four presets become base, contrast, primary and accent, which is what every block then refers to.

A full CSS stack. theme.json declares it; loading a web font is a separate job.

The default width a block gets. Wide blocks get the next one.

Templates

index.html is always written; it is what makes the theme a block theme, and what WordPress falls back to.

Create this folder: wp-content/themes/bucket-block

A block theme is four things in the right places: a style.css header so WordPress lists the theme, a theme.json that defines the presets every block then refers to, templates/index.html so WordPress treats it as a block theme at all, and template parts declared in theme.json so the editor lets you edit the header and footer as parts.

This writes all four, plus the templates you tick, plus the one piece of PHP a block theme cannot do without.

How to use

  1. Name the theme. The folder name defaults to the name, slugged, and is also the text domain.
  2. Set the four palette colours. They become the presets base, contrast, primary and accent, and everything else in theme.json refers to them by name rather than repeating the hex. Change a colour later in one place.
  3. Set the two font stacks and the two layout widths.
  4. Tick the templates you want. index.html is always written.
  5. Create the folder in wp-content/themes/, then create each file from the tabs. The folder must match the folder name field.
  6. Activate the theme, then open Appearance → Editor and everything is editable in place.

Example

With the defaults, theme.json says this about a button:

"button": {
	"color": {
		"background": "var:preset|color|primary",
		"text": "var:preset|color|base"
	},
	"border": { "radius": "4px" }
}

Not #1E56EC. The preset name, which WordPress compiles to var(--wp--preset--color--primary) in the stylesheet it generates. Change the primary colour in one place and every button, link and accent moves with it, in the editor as well as on the front end.

The templates are block markup, the same format the site editor saves:

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
	<!-- wp:query {"queryId":1,"query":{"perPage":10,"postType":"post","inherit":true}} -->
	<div class="wp-block-query">
		<!-- wp:post-template -->
			<!-- wp:post-title {"level":2,"isLink":true} /-->
		<!-- /wp:post-template -->
	</div>
	<!-- /wp:query -->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Nothing there is a placeholder. That is a working index template.

Pitfalls

WordPress never enqueues style.css. Not for block themes either: the only thing in core that calls get_stylesheet_uri() is get_bloginfo(). Without the generated functions.php, the stylesheet is read by the Themes screen and by no browser. Leave Add functions.php on unless you know you want that.

The folder name has to match. WordPress identifies a theme by its folder, and the text domain in style.css should match it, or translations will not load.

templates/index.html is what makes it a block theme. Without that one file WordPress treats the folder as a classic theme, ignores theme.json templates, and looks for index.php.

Editing in the site editor writes to the database, not to your files. Once a template is customised in Appearance → Editor, the database copy wins. Use Reset on a template to go back to the file.

A font stack in theme.json does not load a font. It declares a family. For a web font, either add fontFace entries pointing at files in the theme, or use the WordPress font library, which downloads and self-hosts them.

defaultPalette is off. The generated theme offers your four colours and not WordPress’s default set, which is deliberate: a palette of twenty colours is how a site ends up with twenty colours in it.

Compatibility

Every file is also downloadable as a single .zip, built in your browser. The archive stores the files rather than deflating them, which is what WordPress’s own installer reads, and the whole set goes in a folder named after the theme, so Appearance → Themes → Add New → Upload installs it directly. The writer was checked by installing what it produces through WP-CLI on WordPress 7.1.2, activating it, and loading the home page.

The output targets theme.json version 3, which WordPress 6.6 and later read; WordPress 6.5 reads version 2 and ignores a few version 3 keys, which is why the default requirement is 6.5 rather than lower. The blocks used in the templates are all core blocks present since 6.1, and the whole theme was checked by writing it into wp-content/themes, letting WP_Theme_JSON compile it and parse_blocks() read every template: no unregistered blocks, no stray markup.

useRootPaddingAwareAlignments and the spacingScale need 6.1 and later. Fluid typography needs 6.1. The :hover style on elements needs 6.2.

Frequently asked questions

Is this a starter theme or a finished theme?
A finished small theme. It has a palette, a type scale, spacing presets, a header, a footer, a post loop with pagination and a no-results case, and comments on single posts. What it does not have is patterns, style variations or a block stylesheet, because those are decisions about a specific site.
Where do style variations go?
In styles/*.json, each one a partial theme.json. Copy the generated theme.json, cut it down to the settings.color and styles you want to change, and save it as styles/dark.json. It then appears in the site editor’s style switcher.
Can I add a custom template, like a landing page?
Yes. Add the file to templates/, then declare it in theme.json under customTemplates with a name, title and the postTypes it applies to. Without the declaration WordPress will not offer it in the page editor.
Why is there so little CSS?
Because theme.json compiles to about six kilobytes of custom properties and element styles on its own, and anything you write in style.css has to fight it. Put design decisions in theme.json; keep style.css for the handful of things it cannot express.
How do I make a child of this theme?
Add a Template: line naming this theme’s folder to the child’s style.css. For block themes the child also needs its own templates/ for anything it overrides. The child theme generator on this site writes that scaffold.

From the people who built this tool

WP Adminify

The WordPress admin, rebuilt: a dashboard worth looking at, menu and column control, a real file manager and the login page your client sees.

See WP Adminify Free version on WordPress.org

Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.