The Gutenberg block editor in WordPress has revolutionized content creation and management. One powerful feature of Gutenberg is the ability to create custom blocks that display dynamic data. In this article, we will walk through the process of creating a Dynamic Gutenberg Block that fetches and displays dynamic data from an external API. We will cover everything from registering the block to handling authentication, caching, and rendering the data.
The initial part of this discussion focuses on Gutenberg blocks. Gutenberg is the block-based editor introduced in WordPress 5.0. It creates content using a modular approach. Each piece of content is a block, which can be a paragraph, image, video, or custom block created by developers.
Creating a dynamic block allows you to display content that can change based on external data sources. It is particularly useful for displaying information such as:
By fetching data from an external API, you can ensure that your block always displays the most up-to-date information.

To create a custom Gutenberg block, you first need to set up a WordPress plugin. Here’s how to do it:
<?php
/**
* Plugin Name: Dynamic API Block
* Description: A custom Gutenberg block that fetches data from an external API.
* Version: 1.0
* Author: Your Name
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
function dynamic_api_block_enqueue() {
wp_enqueue_script(
'dynamic-api-block-editor',
plugins_url('block.js', __FILE__),
array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components'),
filemtime(plugin_dir_path(__FILE__) . 'block.js')
);
}
9add_action('enqueue_block_editor_assets', 'dynamic_api_block_enqueue');
Now that you have set up your plugin, the next step is to register your Gutenberg block. In the block.js file, add the following code:
const { registerBlockType } = wp.blocks;
const { useBlockProps } = wp.blockEditor;
registerBlockType('dynamic-api/block', {
title: 'Dynamic API Block',
category: 'widgets',
icon: 'cloud',
edit: () => {
return (
<div {...useBlockProps()}>
<p>Loading data...</p>
</div>
);
},
save: () => {
return null; // Dynamic blocks do not save content in the post
},
});
To fetch data from an external API, you need to specify a render_callback in your block registration. This callback will fetch the data and render the block’s HTML.
Add the following code to your dynamic-api-block.php file to register the block with a render callback:
function dynamic_api_block_register() {
register_block_type('dynamic-api/block', array(
'render_callback' => 'dynamic_api_block_render',
));
}
add_action('init', 'dynamic_api_block_register');
function dynamic_api_block_render($attributes) {
// Fetch data $api_url = 'https://api.example.com/data'; // Replace with your API URL
$response = wp_remote_get($api_url, array(
'headers' => array(
'Authorization' => 'Bearer ' . getenv('API_TOKEN'), // Use environment variable for security
),
));
if (is_wp_error($response)) {
return '<p>Error fetching data.</p>';
}
$data = json_decode(wp_remote_retrieve_body($response), true);
if (empty($data)) {
return '<p>No data available.</p>';
}
// Build the block's HTML
$output = '<div class="dynamic-api-block">';
foreach ($data as $item) {
$output .= '<h2>' . esc_html($item['title']) . '</h2>'; // Adjust according to your API response structure
$output .= '<p>' . esc_html($item['description']) . '</p>';
}
$output .= '</div>';
return $output;
}
Implement WordPress transients to effectively cache data as part of your optimization plan. This will enhance system speed while minimizing API requests. WordPress transients allow you to temporarily store the API response.
Modify the dynamic_api_block_render function to include caching:
function dynamic_api_block_render($attributes) {
$transient_key = 'dynamic_api_block_data';
$data = get_transient($transient_key);
if (false === $data) {
$api_url = 'https://api.example.com/data'; // Replace with your API URL
$response = wp_remote_get($api_url, array(
'headers' => array(
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
),
));
if (is_wp_error($response)) {
return '<p>Error fetching data.</p>';
}
$data = json_decode(wp_remote_retrieve_body($response), true);
if (empty($data)) {
return '<p>No data available.</p>';
}
// Store the data in a transient for 1 hour
set_transient($transient_key, $data, HOUR_IN_SECONDS);
}
// Build the block's HTML
$output = '<div class="dynamic-api-block">';
foreach ($data as $item) {
$output .= '<h2>' . esc_html($item['title']) . '</h2>';
$output .= '<p>' . esc_html($item['description']) . '</p>';
}
$output .= '</div>';
return $output;
}
When working with APIs, authentication is often required. In this example, we used a Bearer token for authentication. Here’s how to securely manage your API credentials:
In your dynamic_api_block_enqueue function, you can add:
1function dynamic_api_block_enqueue() {
2 wp_enqueue_script(
3 'dynamic-api-block-editor',
4 plugins_url('block.js', __FILE__),
5 array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components'),
6 filemtime(plugin_dir_path(__FILE__) . 'block.js')
7 );
8
9 wp_localize_script('dynamic-api-block-editor', 'dynamicApiBlock', array(
10 'apiToken' => getenv('API_TOKEN'),
11 ));
12}
In your block.js, you can access the token using dynamicApiBlock.apiToken.
After implementing the above steps, it’s time to test your block:
To improve the user experience, consider adding loading indicators or error messages directly in the block. You can modify the edit function in your block.js to show a loading spinner or a message when the block is being rendered.
const { registerBlockType } = wp.blocks;
const { useBlockProps } = wp.blockEditor;
const { useEffect, useState } = wp.element;
registerBlockType('dynamic-api/block', {
title: 'Dynamic API Block',
category: 'widgets',
icon: 'cloud',
edit: () => {
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data') // Replace with your API URL
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(() => {
setLoading(false);
});
}, []);
return (
<div {...useBlockProps()}>
{loading ? (
<p>Loading data...</p>
) : (
data && data.map(item => (
<div key={item.id}>
<h2>{item.title}</h2>
<p>{item.description}</p>
</div>
))
)}
</div>
);
},
save: () => {
return null; // Dynamic blocks do not save content in the post
},
});
Creating a dynamic Gutenberg block that fetches data from an external API is a powerful way to enhance your WordPress site. By following the guidelines in this article, you can build a block that not only displays dynamic content but also effectively handles authentication and caching.
With the knowledge gained from this guide, you can explore further possibilities, such as integrating multiple APIs, adding more complex data handling, or even creating a settings page for your block to allow users to customize the API endpoint or other parameters. The flexibility of Gutenberg and the WordPress ecosystem opens up a world of opportunities for developers looking to create engaging and dynamic content.

Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.