Quick answer: To build ACF Gutenberg blocks, create a block folder with a block.json file that includes an acf key and a renderTemplate, register it with register_block_type() on init, create an ACF field group with the location Block is equal to your block, and output the fields in a PHP template with get_field(). It needs ACF PRO 6+ or Secure Custom Fields.
Most of the custom WordPress themes I build use ACF blocks instead of a page builder. Clients get clean blocks in the normal WordPress editor (a testimonial, a pricing table, a hero), they fill in simple fields, and the design cannot break. The code side is small once you know the modern block.json method. This guide builds one complete block you can copy.

Table of Contents
What are ACF Gutenberg blocks?
ACF blocks are custom blocks for the WordPress block editor (Gutenberg) where the content comes from ACF fields and the HTML comes from a PHP template. You get the editing experience of Gutenberg without writing React. Block support needs ACF PRO; Secure Custom Fields (SCF), the free fork maintained by WordPress.org, also includes it. The official reference is the ACF blocks documentation.
Before you start
- WordPress 6.x with ACF PRO 6+ or Secure Custom Fields active.
- A theme or small plugin where you can add files.
- A clear idea of the block: which fields the editor fills in and what the HTML output is.
Build ACF Gutenberg blocks in 4 steps
1. Create the block folder and block.json
Create blocks/testimonial/ in your theme. The block.json file describes the block, and the acf key tells ACF to render it with a PHP template.
{
"name": "acf/testimonial",
"title": "Testimonial",
"description": "A client quote with name and photo.",
"category": "text",
"icon": "format-quote",
"keywords": ["quote", "review"],
"acf": {
"mode": "preview",
"renderTemplate": "testimonial.php"
},
"supports": {
"align": false,
"anchor": true
},
"style": "file:./testimonial.css"
}
2. Register the block
Register every block folder from functions.php. WordPress reads block.json, and ACF takes over rendering.
add_action( 'init', function () {
register_block_type( get_stylesheet_directory() . '/blocks/testimonial' );
} );
3. Add the fields
In ACF, create a field group with a Textarea quote, a Text name, a Text company and an Image photo (return format: ID). Under Location choose Block is equal to Testimonial. The fields now appear in the block sidebar or inline in the editor.
4. Write the render template
The template receives $block and $is_preview. Use get_field() as usual and always escape output.
<?php
$quote = get_field( 'quote' );
$name = get_field( 'name' );
$company = get_field( 'company' );
$photo = get_field( 'photo' );
$anchor = ! empty( $block['anchor'] ) ? ' id="' . esc_attr( $block['anchor'] ) . '"' : '';
if ( ! $quote && $is_preview ) {
echo '<p>Add a quote in the block settings.</p>';
return;
}
?>
<figure class="testimonial"<?php echo $anchor; ?>>
<blockquote><?php echo esc_html( $quote ); ?></blockquote>
<figcaption>
<?php if ( $photo ) { echo wp_get_attachment_image( $photo, 'thumbnail', false, array( 'class' => 'testimonial__photo' ) ); } ?>
<strong><?php echo esc_html( $name ); ?></strong>
<?php if ( $company ) : ?><span><?php echo esc_html( $company ); ?></span><?php endif; ?>
</figcaption>
</figure>
Tips from real projects
- Keep one folder per block with its block.json, template and CSS, so you can copy blocks between projects.
- Load CSS from block.json; WordPress only prints it on pages that use the block, which keeps pages fast.
- Use
$is_previewto show a friendly placeholder in the editor when fields are empty. - Prefer a few flexible blocks over dozens of nearly identical ones.
- For lists of items, use an ACF Repeater field inside the block.
ACF blocks or a page builder?
ACF blocks are the better choice when the design must stay consistent and the site must be very fast, because the output is exactly the HTML you write. A page builder like Elementor is better when editors need to design new layouts themselves. I compare both in detail in ACF vs Elementor, and you can find more ACF code in my ACF code snippets.
Frequently asked questions
Do ACF blocks need ACF PRO?
Yes, blocks are an ACF PRO feature. Secure Custom Fields, the free fork available on WordPress.org, also supports ACF blocks.
Should I use acf_register_block_type or block.json?
Use block.json. It is the method recommended since ACF 6 and matches how core WordPress blocks are registered. acf_register_block_type still works on older sites.
Are ACF blocks fast?
Yes. They render plain PHP and HTML, and block CSS loaded through block.json is only printed on pages that use the block.
Can clients edit ACF blocks without breaking the design?
Yes. Editors only fill in fields, so layout and styling stay controlled by the theme.
Need a custom theme built with ACF blocks? Send me your design for a fixed quote, or message me on WhatsApp.


