How to Create Custom ACF Gutenberg Blocks Without React

Gutenberg blocks are usually built using JavaScript, React, and build tools like Webpack or @wordpress/scripts. However, if you need to build custom blocks quickly without setting up a complex JavaScript development environment, ACF Pro (Advanced Custom Fields) offers a powerful PHP-based alternative.

With ACF, you can create fully custom Gutenberg blocks using familiar PHP templates, standard WordPress field groups, and basic CSS/JS assets.

1. Registering a Custom ACF Block

There are two ways to register an ACF block: using block.json (the modern standard) or via the acf_register_block_type() PHP function.

Here is how to register a custom “Hero Banner” block using PHP in your theme’s functions.php:

				
					add_action('acf/init', 'wg_register_acf_blocks');

function wg_register_acf_blocks() {
    if (function_exists('acf_register_block_type')) {
        acf_register_block_type([
            'name'            => 'hero-banner',
            'title'           => __('Hero Banner', 'webgarage'),
            'description'     => __('A custom hero banner block built with ACF.', 'webgarage'),
            'render_template' => 'template-parts/blocks/hero-banner/hero-banner.php',
            'category'        => 'layout',
            'icon'            => 'cover-image',
            'keywords'        => ['hero', 'banner', 'acf'],
            'enqueue_assets'  => function() {
                wp_enqueue_style('hero-banner-css', get_template_directory_uri() . '/template-parts/blocks/hero-banner/hero-banner.css');
            },
        ]);
    }
}
				
			

Key configuration parameters:

name: A unique identifier for your block.
render_template: The relative path to the PHP template file that renders the block’s HTML on the frontend and in the block editor.
enqueue_assets: Automatically loads block-specific styles and scripts only when the block is present on the page.

2. Attaching Fields to the Block in ACF

Once your block is registered, you need to create the field group in the WordPress dashboard:

  1. Go to ACF → Field Groups in your WordPress admin panel and click Add New.
  2. Add the fields required for your Hero Banner block, for example:
    Title (Field Type: Text)
    Subtitle (Field Type: Textarea)
    Background Image (Field Type: Image — return format set to Image Array or Image URL)
    Button Text (Field Type: Text)
    Button URL (Field Type: URL or Link)
  3. Under the Location Rules section, set the condition to:
    Block is equal to Hero Banner (or your custom block name).

  4. Save changes.

3. Rendering the Block Template (PHP)

Now create the template file at template-parts/blocks/hero-banner/hero-banner.php. In this file, you can retrieve field values using standard ACF functions like get_field() and render clean HTML.
				
					<?php
/**
 * Hero Banner Block Template.
 *
 * @param array $block The block settings and attributes.
 * @param string $content The block inner HTML (if applicable).
 * @param bool $is_preview True during AJAX preview.
 * @param int|string $post_id The post ID this block is saved to.
 */

// Create anchor attribute for smooth scrolling support
$anchor = '';
if (!empty($block['anchor'])) {
    $anchor = 'id="' . esc_attr($block['anchor']) . '" ';
}

// Create class attribute supporting custom class names from Gutenberg sidebar
$class_name = 'hero-banner-block';
if (!empty($block['className'])) {
    $class_name .= ' ' . $block['className'];
}

// Load ACF field values
$title      = get_field('title');
$subtitle   = get_field('subtitle');
$bg_image   = get_field('background_image');
$button_txt = get_field('button_text');
$button_url = get_field('button_url');

$bg_style = '';
if ($bg_image) {
    $bg_style = 'style="background-image: url(' . esc_url($bg_image['url'] ?? $bg_image) . ');"';
}
?>

<section <?php echo $anchor; ?>class="<?php echo esc_attr($class_name); ?>" <?php echo $bg_style; ?>>
    <div class="hero-banner-container">
        <?php if ($title): ?>
            <h1 class="hero-banner-title"><?php echo esc_html($title); ?></h1>
        <?php endif; ?>

        <?php if ($subtitle): ?>
            <p class="hero-banner-subtitle"><?php echo esc_html($subtitle); ?></p>
        <?php endif; ?>

        <?php if ($button_url && $button_txt): ?>
            <a href="<?php echo esc_url($button_url); ?>" class="hero-banner-button">
                <?php echo esc_html($button_txt); ?>
            </a>
        <?php endif; ?>
    </div>
</section>
				
			

Key features of this template approach:

$block['className'] & $block['anchor']: Ensures support for standard Gutenberg block settings (custom CSS classes and HTML anchors).
Native ACF Integration: Standard get_field() syntax allows you to query fields exactly as you would in traditional theme development.

4. Adding Styles for the Block

Create the CSS file at template-parts/blocks/hero-banner/hero-banner.css. These styles will be enqueued automatically both on the frontend and inside the Gutenberg editor:
				
					.hero-banner-block {
    position: relative;
    padding: 80px 20px;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: #ffffff;
    text-align: center;
    border-radius: 8px;
}

.hero-banner-container {
    max-width: 800px;
    margin: 0 auto;
}

.hero-banner-title {
    font-size: 2.5rem;
    margin-bottom: 16px;
    color: inherit;
}

.hero-banner-subtitle {
    font-size: 1.25rem;
    margin-bottom: 24px;
    opacity: 0.9;
}

.hero-banner-button {
    display: inline-block;
    padding: 12px 28px;
    background-color: #0073aa;
    color: #ffffff;
    text-decoration: none;
    border-radius: 4px;
    font-weight: 600;
    transition: background-color 0.2s ease;
}

.hero-banner-button:hover {
    background-color: #005177;
    color: #ffffff;
}
				
			

Creating Gutenberg blocks with ACF Pro gives you the flexibility of WordPress’s modern block editor without the complexity of managing React states, Webpack builds, or Node.js dependencies. It is an ideal approach for agency projects and custom client builds that require fast development cycles.

Be sure to check out our previous tutorials on WordPress development:
Building Custom Gutenberg Blocks Without Webpack: A Practical Dynamic Block Example
Creating Custom Admin Pages using WP_List_Table and WP_User_Query

Need help with your project? We will be happy to help with your project. Feel free to contact us. We can also assist with custom Gutenberg or WordPress development. Just reach out and we will reply soon.

Comments

No comments yet

Share Your Thoughts

Join the conversation!

Scroll to Top

Share Your Thoughts

Thank you for your comment!

Your email address will not be published. Required fields are marked *

Pro

Thank you for reaching out! We’ll be in touch within 24 hours to discuss your project

Standard

Thank you for reaching out! We’ll be in touch within 24 hours to discuss your project

Basic

Thank you for reaching out! We’ll be in touch within 24 hours to discuss your project