{"id":5517,"date":"2026-02-12T20:44:40","date_gmt":"2026-02-13T01:44:40","guid":{"rendered":"https:\/\/chubes.net\/?documentation=innerblocks"},"modified":"2026-03-13T03:27:51","modified_gmt":"2026-03-13T07:27:51","slug":"innerblocks","status":"publish","type":"documentation","link":"https:\/\/chubes.net\/docs\/wordpress-core\/block-development\/innerblocks\/","title":{"rendered":"InnerBlocks"},"content":{"rendered":"<p>InnerBlocks allows blocks to contain other blocks as children, creating nested block structures.<\/p><h2 class=\"wp-block-heading\">Basic Usage<\/h2><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">import { useBlockProps, InnerBlocks } from &#039;@wordpress\/block-editor&#039;;\n\nexport default function Edit() {\n    return (\n        &lt;div { ...useBlockProps() }&gt;\n            &lt;InnerBlocks \/&gt;\n        &lt;\/div&gt;\n    );\n}\n\nexport function Save() {\n    return (\n        &lt;div { ...useBlockProps.save() }&gt;\n            &lt;InnerBlocks.Content \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">InnerBlocks Props<\/h2><h3 class=\"wp-block-heading\"><code>allowedBlocks<\/code><\/h3><p>Restrict which blocks can be inserted:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">const ALLOWED_BLOCKS = [ &#039;core\/paragraph&#039;, &#039;core\/heading&#039;, &#039;core\/image&#039; ];\n\nexport default function Edit() {\n    return (\n        &lt;div { ...useBlockProps() }&gt;\n            &lt;InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><p>In block.json:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">json<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-json\"><code class=\"language-json\">{\n    &quot;allowedBlocks&quot;: [ &quot;core\/paragraph&quot;, &quot;core\/heading&quot;, &quot;core\/image&quot; ]\n}<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>template<\/code><\/h3><p>Define default block structure:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">const TEMPLATE = [\n    [ &#039;core\/heading&#039;, { level: 2, placeholder: &#039;Title&#039; } ],\n    [ &#039;core\/paragraph&#039;, { placeholder: &#039;Description&#039; } ],\n    [ &#039;core\/image&#039;, {} ],\n];\n\nexport default function Edit() {\n    return (\n        &lt;div { ...useBlockProps() }&gt;\n            &lt;InnerBlocks template={ TEMPLATE } \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><p>Nested templates:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">const TEMPLATE = [\n    [ &#039;core\/columns&#039;, {}, [\n        [ &#039;core\/column&#039;, {}, [\n            [ &#039;core\/image&#039;, {} ],\n        ] ],\n        [ &#039;core\/column&#039;, {}, [\n            [ &#039;core\/heading&#039;, { level: 3 } ],\n            [ &#039;core\/paragraph&#039;, {} ],\n        ] ],\n    ] ],\n];<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>templateLock<\/code><\/h3><p>Control template modifications:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">\/\/ No new blocks, can&#039;t remove\/reorder\n&lt;InnerBlocks templateLock=&quot;all&quot; \/&gt;\n\n\/\/ Can reorder but can&#039;t add\/remove\n&lt;InnerBlocks templateLock=&quot;insert&quot; \/&gt;\n\n\/\/ Can&#039;t reorder but can add\/remove (WordPress 6.3+)\n&lt;InnerBlocks templateLock=&quot;contentOnly&quot; \/&gt;\n\n\/\/ No restrictions (default)\n&lt;InnerBlocks templateLock={ false } \/&gt;<\/code><\/pre><\/div><figure class=\"wp-block-table\"><table><thead><tr><th>Value<\/th><th>Add\/Remove<\/th><th>Reorder<\/th><th>Edit Content<\/th><\/tr><\/thead><tbody><tr><td><code>false<\/code><\/td><td>\u2713<\/td><td>\u2713<\/td><td>\u2713<\/td><\/tr><tr><td><code>&quot;all&quot;<\/code><\/td><td>\u2717<\/td><td>\u2717<\/td><td>\u2713<\/td><\/tr><tr><td><code>&quot;insert&quot;<\/code><\/td><td>\u2717<\/td><td>\u2713<\/td><td>\u2713<\/td><\/tr><tr><td><code>&quot;contentOnly&quot;<\/code><\/td><td>\u2713<\/td><td>\u2717<\/td><td>\u2713<\/td><\/tr><\/tbody><\/table><\/figure><h3 class=\"wp-block-heading\"><code>orientation<\/code><\/h3><p>Set insertion orientation hint:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">\/\/ Horizontal layout (row)\n&lt;InnerBlocks orientation=&quot;horizontal&quot; \/&gt;\n\n\/\/ Vertical layout (column) - default\n&lt;InnerBlocks orientation=&quot;vertical&quot; \/&gt;<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>renderAppender<\/code><\/h3><p>Customize the block appender:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">import { InnerBlocks, ButtonBlockAppender } from &#039;@wordpress\/block-editor&#039;;\n\n\/\/ Default appender button\n&lt;InnerBlocks renderAppender={ InnerBlocks.DefaultBlockAppender } \/&gt;\n\n\/\/ Button appender\n&lt;InnerBlocks renderAppender={ ButtonBlockAppender } \/&gt;\n\n\/\/ No appender\n&lt;InnerBlocks renderAppender={ false } \/&gt;\n\n\/\/ Custom appender\n&lt;InnerBlocks\n    renderAppender={ () =&gt; (\n        &lt;button onClick={ \/* insert logic *\/ }&gt;\n            Add Custom Block\n        &lt;\/button&gt;\n    ) }\n\/&gt;<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>placeholder<\/code><\/h3><p>Custom placeholder when empty:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">&lt;InnerBlocks\n    placeholder={\n        &lt;div className=&quot;my-placeholder&quot;&gt;\n            &lt;p&gt;Drag blocks here or click to add&lt;\/p&gt;\n        &lt;\/div&gt;\n    }\n\/&gt;<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>defaultBlock<\/code><\/h3><p>Default block type when pressing Enter:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">&lt;InnerBlocks\n    defaultBlock={ [ &#039;core\/paragraph&#039;, { placeholder: &#039;Type here...&#039; } ] }\n\/&gt;<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>directInsert<\/code><\/h3><p>Skip inserter modal for single allowed block:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">&lt;InnerBlocks\n    allowedBlocks={ [ &#039;core\/paragraph&#039; ] }\n    directInsert={ true }\n\/&gt;<\/code><\/pre><\/div><h3 class=\"wp-block-heading\"><code>prioritizedInserterBlocks<\/code><\/h3><p>Prioritize blocks in inserter:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">&lt;InnerBlocks\n    prioritizedInserterBlocks={ [ &#039;core\/paragraph&#039;, &#039;core\/image&#039; ] }\n\/&gt;<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">useInnerBlocksProps Hook<\/h2><p>For more control over the wrapper element:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">import { useBlockProps, useInnerBlocksProps } from &#039;@wordpress\/block-editor&#039;;\n\nexport default function Edit() {\n    const blockProps = useBlockProps();\n    const innerBlocksProps = useInnerBlocksProps( blockProps, {\n        allowedBlocks: [ &#039;core\/paragraph&#039; ],\n        template: [ [ &#039;core\/paragraph&#039;, {} ] ],\n    } );\n    \n    return &lt;div { ...innerBlocksProps } \/&gt;;\n}<\/code><\/pre><\/div><p>Separate wrapper and inner content:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">export default function Edit() {\n    const blockProps = useBlockProps();\n    const { children, ...innerBlocksProps } = useInnerBlocksProps(\n        { className: &#039;inner-content&#039; },\n        { allowedBlocks: [ &#039;core\/paragraph&#039; ] }\n    );\n    \n    return (\n        &lt;div { ...blockProps }&gt;\n            &lt;header&gt;Block Header&lt;\/header&gt;\n            &lt;div { ...innerBlocksProps }&gt;\n                { children }\n            &lt;\/div&gt;\n            &lt;footer&gt;Block Footer&lt;\/footer&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><p>Save with separate structure:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">export function Save() {\n    const blockProps = useBlockProps.save();\n    const innerBlocksProps = useInnerBlocksProps.save( {\n        className: &#039;inner-content&#039;,\n    } );\n    \n    return (\n        &lt;div { ...blockProps }&gt;\n            &lt;header&gt;Block Header&lt;\/header&gt;\n            &lt;div { ...innerBlocksProps } \/&gt;\n            &lt;footer&gt;Block Footer&lt;\/footer&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Dynamic Blocks with InnerBlocks<\/h2><p>In render.php, inner blocks content is available as <code>$content<\/code>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">&lt;?php\n\/\/ render.php\n$wrapper_attributes = get_block_wrapper_attributes();\n?&gt;\n&lt;div &lt;?php echo $wrapper_attributes; ?&gt;&gt;\n    &lt;header class=&quot;block-header&quot;&gt;\n        &lt;?php echo esc_html( $attributes[&#039;title&#039;] ); ?&gt;\n    &lt;\/header&gt;\n    &lt;div class=&quot;inner-content&quot;&gt;\n        &lt;?php echo $content; \/\/ Inner blocks HTML ?&gt;\n    &lt;\/div&gt;\n    &lt;footer class=&quot;block-footer&quot;&gt;\n        Footer content\n    &lt;\/footer&gt;\n&lt;\/div&gt;<\/code><\/pre><\/div><p>In render_callback:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">function render_my_block( $attributes, $content, $block ) {\n    $wrapper_attributes = get_block_wrapper_attributes();\n    \n    ob_start();\n    ?&gt;\n    &lt;div &lt;?php echo $wrapper_attributes; ?&gt;&gt;\n        &lt;div class=&quot;inner-content&quot;&gt;\n            &lt;?php echo $content; ?&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n    &lt;?php\n    return ob_get_clean();\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Accessing Inner Blocks Data<\/h2><h3 class=\"wp-block-heading\">In JavaScript (Editor)<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">import { useSelect } from &#039;@wordpress\/data&#039;;\nimport { store as blockEditorStore } from &#039;@wordpress\/block-editor&#039;;\n\nexport default function Edit( { clientId } ) {\n    const innerBlocks = useSelect(\n        ( select ) =&gt; select( blockEditorStore ).getBlocks( clientId ),\n        [ clientId ]\n    );\n    \n    const hasInnerBlocks = innerBlocks.length &gt; 0;\n    \n    return (\n        &lt;div { ...useBlockProps() }&gt;\n            { ! hasInnerBlocks &amp;&amp; &lt;p&gt;Add some blocks!&lt;\/p&gt; }\n            &lt;InnerBlocks \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">In PHP<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">function render_my_block( $attributes, $content, $block ) {\n    \/\/ Access parsed inner blocks\n    $inner_blocks = $block-&gt;inner_blocks;\n    \n    foreach ( $inner_blocks as $inner_block ) {\n        $block_name = $inner_block-&gt;name;\n        $block_attrs = $inner_block-&gt;attributes;\n        $block_html = render_block( $inner_block );\n    }\n    \n    return &#039;&lt;div&gt;&#039; . $content . &#039;&lt;\/div&gt;&#039;;\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Conditional InnerBlocks<\/h2><p>Show InnerBlocks based on attributes:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">export default function Edit( { attributes } ) {\n    const { showContent } = attributes;\n    \n    return (\n        &lt;div { ...useBlockProps() }&gt;\n            { showContent &amp;&amp; &lt;InnerBlocks \/&gt; }\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Multiple InnerBlocks Areas<\/h2><p>A block can only have one InnerBlocks. For multiple areas, use nested blocks:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">\/\/ Parent block\nconst TEMPLATE = [\n    [ &#039;my-plugin\/header-area&#039;, {} ],\n    [ &#039;my-plugin\/content-area&#039;, {} ],\n    [ &#039;my-plugin\/footer-area&#039;, {} ],\n];\n\nexport default function Edit() {\n    return (\n        &lt;div { ...useBlockProps() }&gt;\n            &lt;InnerBlocks\n                template={ TEMPLATE }\n                templateLock=&quot;all&quot;\n            \/&gt;\n        &lt;\/div&gt;\n    );\n}\n\n\/\/ Each area block has its own InnerBlocks\n\/\/ my-plugin\/header-area\nexport function HeaderEdit() {\n    return (\n        &lt;header { ...useBlockProps() }&gt;\n            &lt;InnerBlocks allowedBlocks={ [ &#039;core\/heading&#039;, &#039;core\/image&#039; ] } \/&gt;\n        &lt;\/header&gt;\n    );\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Layout Support with InnerBlocks<\/h2><p>Enable layout controls for inner blocks:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">json<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-json\"><code class=\"language-json\">{\n    &quot;supports&quot;: {\n        &quot;layout&quot;: true\n    }\n}<\/code><\/pre><\/div><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">import { useBlockProps, useInnerBlocksProps } from &#039;@wordpress\/block-editor&#039;;\n\nexport default function Edit() {\n    const blockProps = useBlockProps();\n    const innerBlocksProps = useInnerBlocksProps( blockProps, {\n        \/\/ Layout is automatically handled via supports\n    } );\n    \n    return &lt;div { ...innerBlocksProps } \/&gt;;\n}<\/code><\/pre><\/div><p>With default layout:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">json<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-json\"><code class=\"language-json\">{\n    &quot;supports&quot;: {\n        &quot;layout&quot;: {\n            &quot;default&quot;: {\n                &quot;type&quot;: &quot;flex&quot;,\n                &quot;flexWrap&quot;: &quot;nowrap&quot;\n            }\n        }\n    }\n}<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Complete Example: Card Block with InnerBlocks<\/h2><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">json<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-json\"><code class=\"language-json\">{\n    &quot;$schema&quot;: &quot;https:\/\/schemas.wp.org\/trunk\/block.json&quot;,\n    &quot;apiVersion&quot;: 3,\n    &quot;name&quot;: &quot;my-plugin\/card&quot;,\n    &quot;title&quot;: &quot;Card&quot;,\n    &quot;category&quot;: &quot;design&quot;,\n    &quot;attributes&quot;: {\n        &quot;title&quot;: {\n            &quot;type&quot;: &quot;string&quot;\n        }\n    },\n    &quot;supports&quot;: {\n        &quot;color&quot;: {\n            &quot;background&quot;: true,\n            &quot;text&quot;: true\n        },\n        &quot;spacing&quot;: {\n            &quot;padding&quot;: true\n        }\n    },\n    &quot;allowedBlocks&quot;: [ &quot;core\/paragraph&quot;, &quot;core\/heading&quot;, &quot;core\/image&quot;, &quot;core\/button&quot; ],\n    &quot;editorScript&quot;: &quot;file:.\/index.js&quot;,\n    &quot;style&quot;: &quot;file:.\/style.css&quot;,\n    &quot;render&quot;: &quot;file:.\/render.php&quot;\n}<\/code><\/pre><\/div><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">\/\/ edit.js\nimport { useBlockProps, useInnerBlocksProps, RichText } from &#039;@wordpress\/block-editor&#039;;\n\nconst TEMPLATE = [\n    [ &#039;core\/paragraph&#039;, { placeholder: &#039;Card content...&#039; } ],\n];\n\nexport default function Edit( { attributes, setAttributes } ) {\n    const { title } = attributes;\n    const blockProps = useBlockProps( { className: &#039;card-block&#039; } );\n    const innerBlocksProps = useInnerBlocksProps(\n        { className: &#039;card-content&#039; },\n        {\n            template: TEMPLATE,\n            templateLock: false,\n        }\n    );\n    \n    return (\n        &lt;div { ...blockProps }&gt;\n            &lt;RichText\n                tagName=&quot;h3&quot;\n                className=&quot;card-title&quot;\n                value={ title }\n                onChange={ ( value ) =&gt; setAttributes( { title: value } ) }\n                placeholder=&quot;Card Title&quot;\n            \/&gt;\n            &lt;div { ...innerBlocksProps } \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">js<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-js\"><code class=\"language-js\">\/\/ save.js\nimport { useBlockProps, useInnerBlocksProps, RichText } from &#039;@wordpress\/block-editor&#039;;\n\nexport default function Save( { attributes } ) {\n    const { title } = attributes;\n    const blockProps = useBlockProps.save( { className: &#039;card-block&#039; } );\n    const innerBlocksProps = useInnerBlocksProps.save( {\n        className: &#039;card-content&#039;,\n    } );\n    \n    return (\n        &lt;div { ...blockProps }&gt;\n            &lt;RichText.Content\n                tagName=&quot;h3&quot;\n                className=&quot;card-title&quot;\n                value={ title }\n            \/&gt;\n            &lt;div { ...innerBlocksProps } \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre><\/div><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">&lt;?php\n\/\/ render.php\n$wrapper_attributes = get_block_wrapper_attributes( [ &#039;class&#039; =&gt; &#039;card-block&#039; ] );\n$title = $attributes[&#039;title&#039;] ?? &#039;&#039;;\n?&gt;\n&lt;div &lt;?php echo $wrapper_attributes; ?&gt;&gt;\n    &lt;?php if ( $title ) : ?&gt;\n        &lt;h3 class=&quot;card-title&quot;&gt;&lt;?php echo wp_kses_post( $title ); ?&gt;&lt;\/h3&gt;\n    &lt;?php endif; ?&gt;\n    &lt;div class=&quot;card-content&quot;&gt;\n        &lt;?php echo $content; ?&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">Best Practices<\/h2><ol class=\"wp-block-list\"><li><p><strong>Always use <code>InnerBlocks.Content<\/code> in Save:<\/strong> The save function must render inner blocks content.<\/p><\/li><li><p><strong>Use templates for structure:<\/strong> Define templates to guide content creation.<\/p><\/li><li><p><strong>Consider template locking:<\/strong> Lock templates when structure is important.<\/p><\/li><li><p><strong>Restrict allowed blocks:<\/strong> Limit to relevant blocks for better UX.<\/p><\/li><li><p><strong>Use <code>useInnerBlocksProps<\/code> for control:<\/strong> Provides more flexibility than <code>&lt;InnerBlocks \/&gt;<\/code> component.<\/p><\/li><li><p><strong>Handle empty state:<\/strong> Show placeholder or instructions when no inner blocks exist.<\/p><\/li><li><p><strong>Test with various content:<\/strong> Ensure your block handles different combinations of inner blocks.<\/p><\/li><\/ol>","protected":false},"excerpt":{"rendered":"<p>InnerBlocks allows blocks to contain other blocks as children, creating nested block structures. Basic Usage import { useBlockProps, InnerBlocks } from &#8216;@wordpress\/block-editor&#8217;; export default function Edit() { return ( &lt;div&#8230;<\/p>\n","protected":false},"featured_media":0,"template":"","meta":{"footnotes":""},"tags":[],"project":[600],"project_type":[749],"class_list":["post-5517","documentation","type-documentation","status-publish","hentry","project-block-development","project_type-wordpress-reference"],"project_info":{"id":589,"name":"WordPress Core","slug":"wordpress-core"},"project_type_info":{"id":749,"name":"WordPress Reference","slug":"wordpress-reference"},"_links":{"self":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5517","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation"}],"about":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/types\/documentation"}],"version-history":[{"count":3,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5517\/revisions"}],"predecessor-version":[{"id":8999,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5517\/revisions\/8999"}],"wp:attachment":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/media?parent=5517"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/tags?post=5517"},{"taxonomy":"project","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project?post=5517"},{"taxonomy":"project_type","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project_type?post=5517"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}