← All posts

Gutenberg InnerBlocks in ACF Blocks: Less Code, Flexible Cards

Card blocks built with ACF work well until one card needs a quote and the next needs a YouTube video. Then you add a field for every case or reach for flexible content. In this video we build an ACF card block in Scripts Organizer, then replace a hardcoded field with Gutenberg InnerBlocks. Editors can drop any block into the card, you write less code, and you don't have to guess what content will be needed later. We also cover the one limit you need to know before you use it.

When to use InnerBlocks

Use InnerBlocks when you can't predict what goes inside part of a block. Fixed fields suit structured data such as a photo or a name. Content that changes from card to card belongs in an InnerBlocks area, so the editor picks which blocks to use.

Create the ACF card block

An InnerBlocks area only works if you turn it on for the block, so do that when you create it.

  1. Go to Scripts Organizer → ACF Blocks and click Add New.
  2. Set the title to Card, pick a dashicon (we used admin-comments), and set Category to Widgets.
  3. Turn on Advanced Mode (Supports), then turn on JSX (for inner blocks). If this toggle is off, InnerBlocks won't work.
  4. Publish the block.

Build the HTML/SCSS structure

This block uses plain PHP markup and SCSS inside Scripts Organizer. You don't need React and you don't need a build step.

First we write the markup: a wrapper div, an image, an h1 title and a paragraph for the content. Next we create the fields:

  1. Open Custom Fields → Add New and name the field group Card.
  2. Add three fields: Team image (team_image, Image), Team title (team_title, Text) and Team content (team_content).
  3. Under Location Rules, set Show this field group if to Block is equal to Card.
  4. Save the changes.

Keep the field names in the same pattern (team_image, team_title, team_content) so the template is easy to read. We use a Chrome extension that adds a Copy code button next to each field in the ACF list. It gives us the PHP output snippet for that field.

Next we add the block to a page and fill in a photo, a name and some Lorem Ipsum. Two changes made the fields easier to use:

  • Team content changed from Text to Text Area, which gives editors more room to type.
  • Team image changed its Return Format to Image ID, so the template can output the image with wp_get_attachment_image().

The styling uses flexbox with a fixed-size, cropped image:

.team_card{
    display: flex;
    gap: 20px;

    img{
        width: 200px;
        height: 200px;
        object-fit: cover;
    }

    .title{
        margin-top: 0;
    }
}

Later in the video we add a background color and some padding to the card, then duplicate it for a second team member.

The problem: rigid fixed fields

Imagine the first card needs a quote and the second needs a YouTube video. With fixed fields you have to go back to the field group and keep adding fields, or set up flexible content. And you still can't know what editors will ask for next month. Every new variation means more fields and more template code.

Replace a field with InnerBlocks

The fix is to let Gutenberg handle the part that changes. Add an <InnerBlocks /> tag to the template where the flexible content should go:

<div class="team_card">
    <?php
    $team_image = get_field( 'team_image' );
    $size = 'full';
    if ( $team_image ) {
        $url = wp_get_attachment_url( $team_image );
        echo wp_get_attachment_image( $team_image, $size );
    }; ?>

    <div class="team_card__content">

        <?php if ( $team_title = get_field( 'team_title' ) ) : ?>
            <h1 class="title">
                <?php echo esc_html( $team_title ); ?>
            </h1>
        <?php endif; ?>
        <?php if ( $team_content = get_field( 'team_content' ) ) : ?>
            <p class="content"><?php echo esc_html( $team_content ); ?></p>
        <?php endif; ?>

        <InnerBlocks />

    </div>

</div>

One thing to watch: the ACF release post we copied the tag from was missing the closing slash. Write it as <InnerBlocks />, because it won't work without the slash.

After that, the Team content field isn't needed anymore. Editors can type text straight into the card, so we removed the field from the template and from the field group, which leaves less code to maintain.

Insert flexible content (quote, embed)

This is where editors see the benefit. Select the card in the editor and a + appears inside it. From there:

  1. Add a Paragraph and paste the text.
  2. Type / to search for blocks, for example Quote.
  3. Add another paragraph, then a YouTube block. Paste the share URL and click Embed.

Each card can hold different content, and you didn't add a single field for it.

Limitation: only one InnerBlocks region

The catch: each block can have only one InnerBlocks region. You can't have two or three separate inner areas in the same block. For a layout like a Columns block, where each column holds its own content, a single ACF block with several InnerBlocks won't work.

Who is this for

  • WordPress developers building ACF blocks who keep adding fields every time a client wants a new content type in a block.
  • Site builders who make card or team-member blocks and want editors to add quotes, text or embeds without touching the template.
  • Scripts Organizer users who want native Gutenberg blocks from PHP and SCSS, without React.

FAQ

How do I enable InnerBlocks in a Scripts Organizer ACF block?

In the block settings, turn on Advanced Mode (Supports), then turn on JSX (for inner blocks). After that, add <InnerBlocks /> in the PHP template where the inner content should render.

Why is my InnerBlocks tag not working?

Check the closing slash. The tag has to be <InnerBlocks />. The snippet we copied was missing the slash, and without it the tag doesn't work.

Can I use more than one InnerBlocks area in one ACF block?

No. Each block supports only one InnerBlocks region. If you need several independent content areas, like columns, this approach won't cover it.

When should I use fixed ACF fields instead of InnerBlocks?

Use fields for structured data that every card has, like the image and the name. Use InnerBlocks for the part that changes between cards, like a quote in one and a video in another.

Do I need React to build this block?

No. The whole block is built with PHP markup, ACF fields and SCSS inside Scripts Organizer.

Get Scripts Organizer → dplugins.com