Custom blocks in 3 files
Define fields in block.json, render them in a template, style with CSS or SCSS. No JavaScript, no build step, no boilerplate.
Define fields in JSON
Add a blockstudio key to your block.json. Define attributes with types like text, toggle, and color. Blockstudio generates the editor UI automatically. 26 field types available, from simple text inputs to repeaters and code editors.
Full JSON Schema support gives you autocomplete and validation in VS Code, PhpStorm, and any editor that supports it.
{
"name": "starter/hero",
"title": "Hero",
"blockstudio": {
"attributes": {
"heading": {
"type": "text"
},
"showCta": {
"type": "toggle",
"label": "Show CTA"
},
"background": {
"type": "color"
}
}
}
}3-file workflow
block.json for fields, a template for markup, an optional stylesheet. No boilerplate, no build step.
React in PHP
RichText, InnerBlocks, and useBlockProps work directly in PHP, Twig, or Blade templates.
SCSS and Tailwind
Use plain CSS, SCSS, or Tailwind CSS. Blockstudio compiles and minifies assets automatically.
26 field types
Text, color, image, repeater, select, code editor, and more. All configured in JSON.
JSON Schema
Full autocomplete and validation in VS Code, PhpStorm, and any editor with JSON Schema support.
Three template languages
PHP out of the box. Twig via Timber. Blade via jenssegers/blade. Same variables, same components.
npm imports
Import npm packages directly in script.js. Downloaded locally for production, CDN in the editor.
Interactivity API
Enable WordPress Interactivity API with a single flag. Works in both the editor and frontend.
React components in PHP templates
Use <RichText /> for inline editing in the block editor and static HTML on the frontend. <InnerBlocks /> for nested child blocks. And useBlockProps to mark the block wrapper. All from a single template file.
In the editor, these become real React components. On the frontend, they render as plain server-side HTML. No JavaScript shipped to your visitors.
<div useBlockProps class="container">
<RichText
class="text-xl font-semibold"
tag="h1"
attribute="richtext"
placeholder="Enter headline"
/>
<?php if ($a['showCta']): ?>
<a href="<?= $a['ctaUrl'] ?>">
<?= $a['ctaLabel'] ?>
</a>
<?php endif; ?>
<InnerBlocks class="mt-4 p-4 border" />
</div>Write in PHP, Twig, or Blade
Use the template language you already know. PHP templates work out of the box. Add Timber for Twig or jenssegers/blade for Blade. Same variables, same components, same behavior.
Template variables $a (attributes), $b (block), $c (context), and $innerBlocks are available in all three languages.
{# index.twig #}
<div useBlockProps class="card">
<RichText
tag="h2"
attribute="title"
placeholder="Card title"
/>
<img src="{{ a.image.url }}"
alt="{{ a.image.alt }}" />
<div class="card__body">
{{ a.description }}
</div>
<InnerBlocks allowedBlocks='["core/button"]' />
</div>Conditional logic and dynamic options
Show and hide fields based on other values. Operators include ==, !=, includes, empty, and comparison operators. Combine multiple conditions with OR logic.
Populate select options dynamically from posts, users, terms, or external APIs. Mix static options with populated data. No hardcoded lists.
{
"attributes": {
"layout": {
"type": "select",
"options": ["default", "featured", "minimal"],
"populate": {
"type": "query",
"query": "posts",
"arguments": {
"post_type": "layout",
"posts_per_page": -1
}
}
},
"columns": {
"type": "range",
"min": 1,
"max": 4,
"conditions": [{
"id": "layout",
"operator": "!=",
"value": "minimal"
}]
}
}
}ES modules without a build step
Add a script.js and it loads as an ES module. Use import syntax natively. Pull packages from npm with the npm: prefix and Blockstudio downloads them locally for production. No bundler, no config.
The editor uses a CDN for instant preview. The frontend uses local modules for zero external dependencies. Same module, same version, enqueued only once.
import { register } from
"npm:swiper@11.0.0/element/bundle";
import "npm:swiper@11.0.0/swiper.min.css";
register();
const el = document.querySelector(".swiper");
Object.assign(el, {
slidesPerView: 3,
spaceBetween: 20,
loop: true,
});
el.initialize();Post meta and options storage
Store field values in post meta or site options alongside block attributes. Queryable via WP_Query.
Conditional logic
Show and hide fields based on other values with operators like ==, !=, includes, empty, and comparisons.
Dynamic populations
Populate select options from posts, users, terms, functions, or external APIs.
Variations and overrides
Register block variations with different defaults. Override any existing block's attributes, assets, or templates.
The official extension kit
Premium site templates, AI system instructions, and a private Discord community. One-time purchase, lifetime updates.
- 150+ site templates
- AI system instructions
- Lifetime updates
- Private Discord community