Dynamic Blocks (Gutenberg)
Dynamic blocks render content at runtime instead of saving full HTML in the database.
Rendering:
Server-side (PHP) — most common
Client-side (JavaScript)
save()must returnnull
When to Use
Data-driven content (posts, APIs)
Frequently changing content
Centralized rendering logic
Basic Dynamic Block (JS)
import { registerBlockType } from '@wordpress/blocks';
registerBlockType('my-plugin/dynamic-block', {
title: 'Dynamic Block',
category: 'widgets',
attributes: {
message: { type: 'string', default: 'Hello' }
},
edit: ({ attributes, setAttributes }) => (
<input
value={attributes.message}
onChange={(e) => setAttributes({ message: e.target.value })}
/>
),
save: () => null
});
Server-side Rendering (PHP)
function render_dynamic_block($attributes) {
$message = $attributes['message'] ?? '';
return '<div>' . esc_html($message) . '</div>';
}
add_action('init', function () {
register_block_type(__DIR__ . '/build', [
'render_callback' => 'render_dynamic_block',
]);
});
No static markup stored
Output always generated via PHP
Use for latest posts, user data, API content
Block Supports
Block Supports allow enabling built-in editor features without custom implementation.
Example
registerBlockType('my-plugin/support-block', {
title: 'Support Block',
supports: {
align: true,
color: {
text: true,
background: true
},
spacing: {
margin: true,
padding: true
}
},
edit: () => <div>Block</div>,
save: () => <div>Block</div>
});
Common Supports
aligncolorspacingtypographyborder
How It Works
Adds UI controls in editor
Stores values in attributes
Applies styles automatically
Block Supports in Dynamic Blocks
Editor Usage
import { useBlockProps } from '@wordpress/block-editor';
edit: () => {
const props = useBlockProps();
return <div {...props}>Editor</div>;
}
PHP Rendering
function render_block($attributes, $content, $block) {
$wrapper = get_block_wrapper_attributes();
return "<div $wrapper>Dynamic Content</div>";
}
Key Notes
Supports still apply in dynamic blocks
Must use
get_block_wrapper_attributes()in PHPEnsures styles (color, spacing, etc.) work on frontend
block.json (Recommended)
{
"apiVersion": 2,
"name": "my-plugin/dynamic-block",
"title": "Dynamic Block",
"category": "widgets",
"supports": {
"color": { "background": true }
}
}