search ]

Create a Custom Gutenberg Block with ACF & block.json

Gutenberg, WordPress’s block editor, simplifies the process of visually creating and managing content. By using Advanced Custom Fields (ACF), you can easily build custom blocks for Gutenberg without extensive knowledge of JavaScript.

Since WordPress 5.8, it is recommended to register blocks using the block.json file instead of PHP functions. In this guide, you’ll learn how to create a custom Call to Action (CTA) block using ACF and the block.json method. Let’s get started!

Step 1: Create the Block Configuration (block.json)

In your theme directory, navigate to /template-parts/blocks/custom-cta/ and create a file named block.json. This file defines the block’s properties and settings:

{
  "apiVersion": 2,
  "name": "acf/custom-cta",
  "title": "Custom CTA Block",
  "description": "A custom call to action block with an image, title, description, and button.",
  "category": "common",
  "icon": "megaphone",
  "keywords": ["cta", "call to action", "button"],
  "supports": {
    "align": ["wide", "full"],
    "html": false
  },
  "acf": {
    "mode": "preview",
    "renderTemplate": "custom-cta.php"
  },
  "enqueueStyle": "template-parts/blocks/custom-cta.css"
}

Note: The enqueueStyle property allows you to define a CSS file that will be automatically loaded when the block is used in the editor and on the frontend. This ensures your styles are applied consistently without additional enqueue functions in PHP.

Explanation of Key Properties:

  • name: The block’s unique identifier.
  • title: The block’s display name.
  • description: A brief explanation of the block.
  • category: Defines where the block appears in Gutenberg.
  • icon: The WordPress Dashicon representing the block.
  • supports: Controls block settings like alignment.
  • acf.renderTemplate: Specifies the PHP file used to render the block.
  • enqueueStyle: Links to the CSS file for styling.

Step 2: Register the Block in functions.php

Although block.json eliminates the need for manual registration, you must ensure WordPress recognizes it. Add this snippet to your functions.php file:

function register_acf_blocks() {
    register_block_type(get_template_directory() . '/template-parts/blocks/custom-cta/block.json');
}
add_action('init', 'register_acf_blocks');

Step 3: Create the ACF Field Group for the Block

1. In your WordPress dashboard, go to ACF > Field Groups.
2. Click Add New to create a new field group.
3. Name the field group Custom CTA Block Fields.

Add the following fields:

  • Title: Add a Text field for the CTA title.
  • Description: Add a Text Area field for the CTA description.
  • Image: Add an Image field for the CTA image.
  • Button Text: Add a Text field for the button label.
  • Button URL: Add a URL field for the button link.
  • Background Color: Add a Color Picker field for setting the block’s background color.

It looks like this:

Create the ACF Field Group for the Block

Create the ACF Field Group for the Block

When you’ve finished adding the fields, go to the “Location Rules” settings in the ACF field group editor. Set the rule to Block is equal to Custom CTA Block.

Add the Relevant Location Rules

Step 4: Create the Block Template

In your theme directory, navigate to template-parts/blocks/custom-cta/ and create a file named custom-cta.php.

<?php
$title = get_field('title');
$description = get_field('description');
$image = get_field('image');
$button_text = get_field('button_text');
$button_url = get_field('button_url');
$background_color = get_field('background_color');
?>

<div class="custom-cta-block" style="background-color: <?php echo esc_attr($background_color); ?>">
    <?php if ($image): ?>
        <img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>" class="cta-image" />
    <?php endif; ?>

    <div class="cta-content">
        <?php if ($title): ?>
            <h3 class="cta-title"><?php echo esc_html($title); ?></h3>
        <?php endif; ?>

        <?php if ($description): ?>
            <p class="cta-description"><?php echo esc_html($description); ?></p>
        <?php endif; ?>

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

Step 5: Add Custom CSS

Create a file at template-parts/blocks/custom-cta.css and add styles:

.custom-cta-block {
    padding: 40px;
    border-radius: 15px;
    text-align: center;
    color: #fff;
    max-width: 700px;
    margin: 30px auto;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.custom-cta-block:hover {
    transform: translateY(-5px);
}

.cta-image {
    max-width: 120px;
    margin-bottom: 20px;
    border-radius: 50%;
    border: 4px solid #fff;
}

.cta-title {
    font-size: 28px;
    margin: 15px 0;
    font-weight: 700;
}

.cta-description {
    font-size: 18px;
    margin-bottom: 20px;
    line-height: 1.5;
}

.cta-button {
    display: inline-block;
    padding: 12px 25px;
    background-color: #ff6b6b;
    color: #fff;
    text-decoration: none;
    border-radius: 25px;
    font-weight: bold;
}

.cta-button:hover {
    background-color: #e05656;
}

Final Thoughts

Using block.json simplifies block registration and ensures future compatibility with WordPress updates. By following these steps, you’ve built a fully functional custom Gutenberg block using ACF!

If you encounter any issues or have questions, feel free to leave a comment below!

3 Comments...
  • Pieter 4 March 2025, 15:01

    Great tutorial, thank you!

    The only thing I would have expected is that you would have written it with `Blocks.json` support in mind:

    > Since WordPress 5.8, WordPress has supported – and recommended – that blocks are registered through a JSON configuration file.

    Source: https://www.advancedcustomfields.com/resources/whats-new-with-acf-blocks-in-acf-6/#blockjson-support

    Maybe an idea for a follow-up post?

    Cheers,
    Pieter

    • רועי יוסף 4 March 2025, 17:08

      Hi Pieter,

      I appreciate the comment…

      You are correct, i’ve modified the post to reflect the update. Thanks again! 🙂

      • Pieter 4 March 2025, 17:20

        Hi Roee,
        Amazing how quick you have adapted your post following my suggestion! Many thanks, truly surprised!
        Pieter

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development