Back to Blog
Lesson 20 of the Advanced WordPress Plugin Engineering: Scale, Security & React UIs course
WordPressJune 27, 20263 min read

InnerBlocks and Nested Structures: Advanced Gutenberg Block Development

Master InnerBlocks in Gutenberg. Learn how to nest blocks, restrict child types, and enforce templates to build complex layouts for your WordPress plugin.

GutenbergWordPressInnerBlocksReactBlock Developmentphpplugin-development

Previously in this course, we covered the foundational aspects of Block API v2 Essentials: Metadata, React Edits, and SSR and how to manage global state using State Management with @wordpress/data: Building Scalable Stores. Building on that knowledge, this lesson focuses on creating complex, hierarchical layouts using InnerBlocks.

For our Knowledge Base plugin, we need a "Documentation Section" block that acts as a container for specific instructional components. Simple blocks aren't enough; we need a nested structure that enforces consistency.

Understanding InnerBlocks from First Principles

In Gutenberg, InnerBlocks is a specialized React component that allows a block to contain other blocks. Think of it as a "drop zone" within your component. When you use InnerBlocks, you aren't just creating a wrapper; you are defining a recursive architecture where the parent block manages the layout, and the children manage the content.

The primary power of InnerBlocks lies in two areas:

  1. Template Enforcement: You can force specific blocks to appear by default inside your container.
  2. Constraint Management: You can whitelist or blacklist which blocks a user is allowed to insert.

Worked Example: The Knowledge Base Section Block

We want to build a <kb-section> block that always contains a header and a list of step-by-step instructions. We will restrict the contents so users can only add our custom kb-step blocks or standard paragraph blocks.

1. Defining the Block Metadata

In your block.json, you must set supports to allow nesting:

JSON
{
    "name": "kb/section",
    "title": "Knowledge Base Section",
    "category": "kb-blocks",
    "supports": {
        "innerBlocks": true
    }
}

2. Implementing the Edit Component

In your edit.js, import InnerBlocks from @wordpress/block-editor. We will define a TEMPLATE constant to pre-populate the container.

JAVASCRIPT
import { InnerBlocks, useBlockProps } from CE9178">'@wordpress/block-editor';

const TEMPLATE = [
    [CE9178">'core/heading', { level: 3, placeholder: CE9178">'Section Title...' }],
    [CE9178">'kb/step', { placeholder: CE9178">'Enter step detail...' }]
];

const ALLOWED_BLOCKS = [CE9178">'core/heading', CE9178">'core/paragraph', CE9178">'kb/step'];

export default function Edit() {
    const blockProps = useBlockProps();

    return (
        <div {...blockProps}>
            <InnerBlocks
                allowedBlocks={ALLOWED_BLOCKS}
                template={TEMPLATE}
                templateLock={false} 
            />
        </div>
    );
}

3. The Save Component

The save function is straightforward. It must output the <InnerBlocks.Content /> component to ensure the nested blocks are rendered correctly in the frontend.

JAVASCRIPT
import { InnerBlocks, useBlockProps } from CE9178">'@wordpress/block-editor';

export default function Save() {
    const blockProps = useBlockProps.save();
    return (
        <div {...blockProps}>
            <InnerBlocks.Content />
        </div>
    );
}

Advanced Configuration: Template Locking

In the example above, templateLock is set to false, allowing users to add or remove blocks. If you are building a rigid UI component, you can use:

  • 'all': Users cannot move, remove, or insert new blocks.
  • 'insert': Users can move or delete blocks, but cannot insert new ones.

Hands-on Exercise

In your current Knowledge Base plugin project, refactor your main "Documentation" block to use InnerBlocks.

  1. Create a TEMPLATE that includes a core/columns block to force a side-by-side layout for large screens.
  2. Set allowedBlocks to only permit core/paragraph and core/image inside those columns.
  3. Verify that the block renders correctly by switching between the visual editor and the code editor to inspect the <!-- wp:innerblocks --> comments.

Common Pitfalls

  • Missing InnerBlocks.Content in Save: If you omit this in the save function, the nested blocks will exist in the database but will not render on the frontend.
  • Over-Restricting: Setting templateLock to 'all' too aggressively can frustrate users. Use it only when the block structure is strictly functional (e.g., a tabbed interface).
  • Missing Block Dependencies: If your allowedBlocks references a custom block, ensure that the custom block is registered before the parent block, otherwise the editor will fail to render the inner blocks correctly.

Recap

We’ve moved from simple block registration to complex, nested architectures. By utilizing InnerBlocks, allowedBlocks, and template definitions, you ensure that your Knowledge Base plugin provides a structured, predictable authoring experience while maintaining the flexibility of the Gutenberg editor. These nested structures are the backbone of professional-grade WordPress page builders and specialized plugin UIs.

Up next: We will connect our nested blocks to the database by implementing Custom REST API Integration to fetch and save live Knowledge Base data.

Similar Posts