Master the Block API v2 by defining block.json metadata, implementing React-based edit functions, and leveraging server-side rendering for your plugin.
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.
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.
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.
JAVASCRIPTimport { 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> ); }
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>
block.json with apiVersion: 2.edit.js, implement a simple TextControl that updates the articleId attribute.render.php file to fetch an article from your database based on that articleId.apiVersion: 2: Without this, you lose access to useBlockProps and the modern wrapper API, forcing you to manually manage class and id attributes.render.php. Use your Repository classes (as we covered in our Data Access Objects Pattern lesson) to keep the template clean.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.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.
Master Gutenberg dynamic block rendering in PHP. Learn to implement render_callback, optimize server-side performance, and cache output for high-traffic sites.
Read moreMaster Gutenberg block evolution. Learn to implement block transforms and deprecation handlers to ensure seamless backward compatibility for your plugin.
Block API v2 Essentials
Custom Hooks for React