Blog Create a custom Gutenberg block from scratch
Create a custom Gutenberg block from scratch
TL;DR A custom block is a small package: a block.json describing it, an edit function for the editor, and a save function for the saved markup. Scaffold it, register it with register_block_type, and manage its data through attributes. Start simple, then add controls.
Custom blocks are how you extend the WordPress editor with your own building pieces. The tooling has settled down a lot, and a modern block is a tidy little package once you have seen its parts. Here is the shape of one.
The pieces of a block
A block is three things working together.
block.jsondescribes the block: its name, title, category, and attributes.- An
editfunction renders the block in the editor, using React. - A
savefunction returns the markup stored in the post.
Register the whole thing and WordPress wires it into the inserter.
Scaffold and register
The official tooling scaffolds a block for you, which saves fighting the build setup. Once you have the files, registration is one call on the server:
add_action( 'init', function () {
register_block_type( __DIR__ . '/build/my-block' );
} );
Pointing at the folder with block.json lets WordPress read everything it needs from there.
Store data with attributes
Attributes are how a block remembers its content and settings. Define them in block.json:
"attributes": {
"message": { "type": "string", "default": "" }
}
Then read and write them in edit:
export default function Edit({ attributes, setAttributes }) {
return (
<RichText
value={attributes.message}
onChange={(message) => setAttributes({ message })}
/>
);
}
The save function returns the same content as static markup, so the editor view and the stored output agree.
Where to grow it
Once the basics work, the editor's component library opens up. Add an InspectorControls sidebar for settings, use BlockControls for a toolbar, and pull in ready-made components for colours, spacing, and alignment instead of building your own.
The advice that saves time
Start with the smallest block that does one thing, and get it saving and reloading cleanly before adding controls. Most block headaches are validation errors from edit and save drifting apart, so keep them in step from the start. A small, correct block is a far better base to build on than an ambitious one that will not save.
FAQ
Do I need React to build a block?
The editor is built on React, so block edit functions use React components and JSX. You do not need to be a React expert to start, but the edit side is React. The save side just returns the markup to store.
What is block.json for?
It is the single source of truth for a block: its name, title, category, attributes, and which scripts and styles it uses. WordPress reads it to register the block, which keeps your PHP and JavaScript in sync.
What is the difference between edit and save?
edit renders the block inside the editor, where it can be interactive. save returns the static markup that gets written into the post content. Keeping them consistent avoids block validation errors.