Back to Blog
Lesson 19 of the Advanced WordPress Plugin Engineering: Scale, Security & React UIs course
WordPressJune 27, 20263 min read

Block API v2 Essentials: Metadata, React Edits, and SSR

Master the Block API v2 by defining block.json metadata, implementing React-based edit functions, and leveraging server-side rendering for your plugin.

GutenbergBlock APIReactWordPress DevelopmentPHPwordpressplugin-development

Previously in this course, we explored State Management with @wordpress/data: Building Scalable Stores and established a robust React Component Architecture: Scaling WordPress Plugin UIs. This lesson pivots to the Block API v2, where we transition from managing application state to rendering that state within the Gutenberg editor.

At this level, "blocks" are no longer just static HTML snippets; they are sophisticated components defined by metadata, managed by React in the editor, and rendered dynamically on the front end.

Defining the block.json Metadata

The block.json file is the source of truth for your block. It replaces the legacy register_block_type PHP arguments, allowing for better performance through selective asset loading.

For our Knowledge Base plugin, we need a block that displays a specific article summary. Here is a production-ready block.json structure:

JSON
{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "kb-plugin/article-summary",
    "title": "Knowledge Base Article Summary",
    "category": "widgets",
    "attributes": {
        "articleId": {
            "type": "integer"
        }
    },
    "editorScript": "file:./index.js",
    "render": "file:./render.php"
}

By defining render, we tell WordPress that this block is dynamic. Instead of using a save() function to serialize HTML to the database, WordPress will execute the PHP file provided whenever the block is rendered on the front end.

Implementing React Edit Functions

The edit function in your index.js acts as the React entry point for the editor UI. Because we are building a Knowledge Base, we often need to fetch data. We use the useSelect hook to pull data from our custom stores, as discussed in our lesson on State Management with @wordpress/data.

JAVASCRIPT
import { useSelect } from CE9178">'@wordpress/data';
import { useBlockProps } from CE9178">'@wordpress/block-editor';

export default function Edit({ attributes, setAttributes }) {
    const { articleId } = attributes;
    
    // Fetch article details from our custom store
    const article = useSelect((select) => {
        return select(CE9178">'kb-plugin/store').getArticle(articleId);
    }, [articleId]);

    const blockProps = useBlockProps();

    return (
        <div {...blockProps}>
            {article ? (
                <h3>{article.title}</h3>
            ) : (
                <p>Select an article to display...</p>
            )}
        </div>
    );
}

Leveraging Server-Side Rendering (SSR)

When you use render_callback or the render property in block.json, you decouple the editor UI from the front-end output. This is vital for a Knowledge Base plugin, as article content might change in the database. If you saved the HTML statically, you would have to update every post whenever an article title changed.

In render.php, you have access to the block's attributes:

PHP
<?php
#6A9955">// render.php
$article_id = $attributes['articleId'] ?? 0;

if (!$article_id) {
    return;
}

$article = KB_Repository::find($article_id);
?>
<div <?php echo get_block_wrapper_attributes(); ?>>
    <h2><?php echo esc_html($article->title); ?></h2>
    <div class="kb-content">
        <?php echo apply_filters('the_content', $article->content); ?>
    </div>
</div>

Hands-on Exercise

  1. Create a new block directory in your plugin.
  2. Define a block.json with apiVersion: 2.
  3. In your edit.js, implement a simple TextControl that updates the articleId attribute.
  4. Implement the render.php file to fetch an article from your database based on that articleId.
  5. Verify that changing the ID in the editor immediately updates the preview (if you implemented a preview state) and the front-end output.

Common Pitfalls

  • Forgetting apiVersion: 2: Without this, you lose access to useBlockProps and the modern wrapper API, forcing you to manually manage class and id attributes.
  • Mixing Logic: Avoid putting complex business logic in render.php. Use your Repository classes (as we covered in our Data Access Objects Pattern lesson) to keep the template clean.
  • Asset Enqueueing: When using block.json, assets are registered automatically. Do not manually enqueue them in functions.php unless you have a specific reason; otherwise, you risk double-loading scripts.

Recap

We have transitioned to the Block API v2, utilizing block.json for metadata, React for the editor experience, and PHP for dynamic rendering. This architecture ensures your Knowledge Base plugin remains performant and data-consistent.

Up next: We will explore InnerBlocks to create complex, nested Knowledge Base layouts.

Similar Posts