When we build websites with WordPress, we encounter the Block Editor. It’s a powerful visual editor that has changed how we create content and design layouts. But when we start developing custom blocks for this editor, we come across two important concepts: static blocks and dynamic blocks.

Understanding the difference between these two types is essential for us as WordPress developers to make informed decisions about performance, customization, and content rendering. In this post, we’ll explore what static and dynamic blocks are, when to use each, and how to create them.

What Are Static and Dynamic Blocks?

Static Blocks

A static block is rendered entirely in JavaScript using React. When we add content to a static block, that content is saved directly into the post content as HTML. This means the content is stored “as is” in the database.

Use static blocks when:

  • The content doesn’t need to change dynamically.
  • The block only requires what the user sees in the editor.
  • We want to optimize performance by avoiding PHP processing during page loads.

Example Use Cases: Headings, paragraphs, buttons, image galleries.

Dynamic Blocks

A dynamic block is rendered on the front end using PHP. The blockโ€™s output is generated every time the page loads, making it ideal for content that changes frequently or depends on server-side logic.

Use dynamic blocks when:

  • The output needs to update frequently (e.g., latest posts, logged-in user data).
  • We want to keep the post content clean and rely on server-side templates.
  • We need advanced customization using PHP logic.

Example Use Cases: Latest posts, post metadata, contact forms, custom listings.

Creating a Static Block

File Structure:

my-plugin/
โ”œโ”€โ”€ alert-box/
โ”‚ โ”œโ”€โ”€ block.json
โ”‚ โ”œโ”€โ”€ edit.js
โ”‚ โ””โ”€โ”€ index.js

block.json

{
  "apiVersion": 3,
  "name": "myplugin/alert-box",
  "title": "Alert Box",
  "category": "widgets",
  "icon": "warning",
  "editorScript": "file:./index.js"
}

index.js

import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';

registerBlockType('myplugin/alert-box', {
    attributes: {
        content: {
            type: 'string',
            source: 'html',
            selector: 'p'
        }
    },
    edit: Edit,
    save({ attributes }) {
        return (
            <div className="alert-box">
                <p>{attributes.content}</p>
            </div>
        );
    }
});

edit.js

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';

export default function Edit({ attributes, setAttributes }) {
    const blockProps = useBlockProps();

    return (
        <div {...blockProps} className="alert-box">
            <RichText
                tagName="p"
                value={attributes.content}
                onChange={(content) => setAttributes({ content })}
                placeholder={__('Add your alert text here...', 'myplugin')}
            />
        </div>
    );
}

This block is fully static. The save function defines exactly what gets stored and rendered.

Creating a Dynamic Block

Dynamic blocks require a PHP render callback. Here’s how we can make a dynamic block that shows the latest post title.

File Structure:

my-plugin/
โ”œโ”€โ”€ latest-post/
โ”‚ โ”œโ”€โ”€ block.json
โ”‚ โ”œโ”€โ”€ index.js
โ”‚ โ””โ”€โ”€ render.php

block.json

{
  "apiVersion": 3,
  "name": "myplugin/latest-post",
  "title": "Latest Post",
  "category": "widgets",
  "icon": "megaphone",
  "editorScript": "file:./index.js",
  "render": "file:./render.php"
}

index.js

import { registerBlockType } from '@wordpress/blocks';

registerBlockType('myplugin/latest-post', {
    edit() {
        return <p>Latest post will be shown here on the frontend.</p>;
    },
    save() {
        // Returning null to indicate dynamic rendering
        return null;
    }
});

render.php

<?php
function myplugin_render_latest_post() {
    $recent_posts = wp_get_recent_posts([
        'numberposts' => 1,
        'post_status' => 'publish',
    ]);

    if (empty($recent_posts)) {
        return '<p>No posts found.</p>';
    }

    $post = $recent_posts[0];
    return sprintf('<h3><a href="%s">%s</a></h3>', esc_url(get_permalink($post['ID'])), esc_html($post['post_title']));
}

Choosing Between Static and Dynamic

When deciding whether to use a static or dynamic block, we should ask:

  • Does this block require real-time data or updates from the server? โ†’ Go dynamic.
  • Is the block mostly decorative or fixed content? โ†’ Use static.
  • Do we need to keep our post content clean from HTML bloat? โ†’ Dynamic blocks can help.

Final Thoughts

The WordPress Block Editor gives us powerful tools to create modern, reusable content structures. By understanding static and dynamic blocks, we can build flexible and performant custom blocks that suit a variety of use cases. Whether weโ€™re building a rich content page or a dynamic listing, thereโ€™s a block type that fits the bill.

Leave a Reply

Your email address will not be published. Required fields are marked *