Create an ACF Block with InnerBlocks

Enable InnerBlocks within an ACF block to allow nesting other Gutenberg blocks inside your custom block.

php blocks
|

Enable InnerBlocks within an ACF block to allow nesting other Gutenberg blocks inside your custom block.

Set "jsx": true in your block.json supports to enable InnerBlocks:

{
    "name": "acf/hero",
    "title": "Hero Section",
    "category": "theme",
    "acf": {
        "mode": "preview",
        "renderTemplate": "blocks/hero/render.php"
    },
    "supports": {
        "align": true,
        "jsx": true
    }
}

In your render template, use <InnerBlocks /> to mark where nested blocks should appear:

<?php
$heading    = get_field( 'heading' );
$background = get_field( 'background_image' );
$allowed    = [ 'core/paragraph', 'core/button', 'core/list' ];
?>

<section class="hero-block" style="background-image: url(<?php echo esc_url( $background['url'] ); ?>)">
    <div class="hero-content">
        <?php if ( $heading ) : ?>
            <h1><?php echo esc_html( $heading ); ?></h1>
        <?php endif; ?>

        <InnerBlocks allowedBlocks="<?php echo esc_attr( wp_json_encode( $allowed ) ); ?>" />
    </div>
</section>

Lock the template to prevent editors from adding or removing blocks:

<InnerBlocks
    allowedBlocks="<?php echo esc_attr( wp_json_encode( [ 'core/paragraph', 'core/button' ] ) ); ?>"
    template="<?php echo esc_attr( wp_json_encode( [
        [ 'core/paragraph', [ 'placeholder' => 'Add a description...' ] ],
        [ 'core/button', [ 'text' => 'Learn More' ] ],
    ] ) ); ?>"
    templateLock="all"
/>

Note: <InnerBlocks /> is rendered as JSX — it only works when the block is in edit mode. On the front end, the nested block content is rendered automatically in its place.

Related Snippets

Stay Updated

Get ACF tips and new extensions in your inbox

No spam. Unsubscribe anytime.