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.
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
- Name the theme. The folder name defaults to the name, slugged, and is also the text domain.
- Set the four palette colours. They become the presets
base,contrast,primaryandaccent, and everything else intheme.jsonrefers to them by name rather than repeating the hex. Change a colour later in one place. - Set the two font stacks and the two layout widths.
- Tick the templates you want.
index.htmlis always written. - Create the folder in
wp-content/themes/, then create each file from the tabs. The folder must match the folder name field. - 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?
Where do style variations go?
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?
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?
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?
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.