Learn to build dynamic Gutenberg blocks that fetch live Knowledge Base data via the REST API. Master the @wordpress/data store integration for your blocks.
Previously in this course, we built a robust custom hook for API logic to streamline our React admin dashboard. Now, we're taking that knowledge into the content editor. In this lesson, we will build a dynamic block that fetches and displays our Knowledge Base entries directly inside the Gutenberg editor, allowing users to select and embed content without leaving the post-editing screen.
A dynamic block is a block that renders its output on the server side using PHP, rather than just saving static HTML to the post_content. This is crucial for our Knowledge Base plugin because if we update a KB entry in our admin dashboard, we want that change to reflect immediately across all posts where the block is used.
Instead of saving the rendered HTML, we save a "placeholder" (the block attributes) and let the render_callback handle the database query and output generation.
To make this work, we need to bridge our existing API infrastructure with the Block Editor's data store. We will use the @wordpress/data package, which we explored when registering a custom data store, to fetch our KB entries.
First, we define our block in PHP. We need to register the block type and provide a render_callback function.
PHP#6A9955">// kb-plugin/blocks/kb-display/index.php register_block_type( 'kb-plugin/kb-display', array( 'attributes' => array( 'kbId' => array( 'type' => 'integer', ), ), 'render_callback' => 'render_kb_display_block', ) ); function render_kb_display_block( $attributes ) { if ( empty( $attributes['kbId'] ) ) { return '<p>Please select a Knowledge Base entry.</p>'; } #6A9955">// Fetch the specific KB entry using our established service layer $post = get_post( $attributes['kbId'] ); return sprintf( '<div class="kb-entry"><h2>%s</h2>%s</div>', esc_html( $post->post_title ), apply_filters( 'the_content', $post->post_content ) ); }
In our JavaScript block code, we need to display a dropdown or list of available KB entries. We'll use useSelect to query our custom data store.
JAVASCRIPT// kb-plugin/src/blocks/kb-display/edit.js import { useSelect } from CE9178">'@wordpress/data'; import { SelectControl } from CE9178">'@wordpress/components'; export default function Edit( { attributes, setAttributes } ) { const { kbId } = attributes; const { kbEntries, isResolving } = useSelect( ( select ) => { const store = select( CE9178">'kb-plugin/data' ); return { kbEntries: store.getEntries(), isResolving: store.isResolving( CE9178">'getEntries' ), }; }, [] ); if ( isResolving ) return <p>Loading entries...</p>; return ( <SelectControl label="Select KB Entry" value={ kbId } options={ [ { label: CE9178">'Select one...', value: 0 }, ...kbEntries.map( ( e ) => ( { label: e.title.rendered, value: e.id } ) ), ] } onChange={ ( val ) => setAttributes( { kbId: parseInt( val ) } ) } /> ); }
blocks/kb-display in your plugin.register_block_type.edit.js file provided above.package.json is configured to build the new block assets using @wordpress/scripts.npm run build and verify that the block appears in the editor and successfully populates the SelectControl with your KB entries.kbId attribute in the PHP registration, the editor won't know how to save the block state to the database.edit.js runs in the browser, while the render_callback runs on the server. Do not try to call get_posts() inside your edit.js file; always use the REST API via your store.We've successfully bridged the gap between our React admin dashboard and the Gutenberg editor. By creating a dynamic block, we keep our content presentation decoupled from the block's storage. We've utilized our existing REST API and data store to power the block's UI, ensuring a consistent developer experience across the entire plugin.
Up next: We will address potential data conflicts by implementing optimistic locking to ensure that multiple editors don't overwrite each other's changes.
Learn to build a robust audit system by hooking into the WordPress REST API, logging changes to a custom table, and displaying the history in your React UI.
Read moreLearn to build a safe, user-centric Modal confirmation system in your WordPress React admin UI to prevent accidental data loss during API operations.
Integrating with Gutenberg Blocks
Unit Testing React Components
Handling Large Datasets with GraphQL
Implementing Real-time Updates with Web