Limiting the block count for InnerBlocks
Tags: tutorials, blockdevelopment, gutenberg, innerblocks
Published: 2020-11-11 17:47:10

---
title: Limiting the block count for InnerBlocks
published: true
date: 2020-10-09 18:44:00 UTC
tags: Tutorials,BlockDevelopment,Gutenberg,InnerBlocks
canonical_url: https://ryanwelcher.com/2020/10/limiting-the-block-count-for-innerblocks/
---

One of the most versatile components that Gutenberg block developers have is the `<InnerBlocks/>` component. This component allows other blocks to be inserted into it. WordPress Core ships with the Group and Columns blocks that both use InnerBlocks internally to allow the creation of very complex block structures.

The InnerBlocks component solves some interesting problems for custom blocks, for example creating a list of ordered items. By leveraging InnerBlocks, one can skip having to build a bespoke system and rely on Gutenberg to handle the insertion, deletion, and ordering of items. It is very flexible and easy to use. However, while working with it I discovered that there is no built-in way to limit the number of blocks that can be inserted.

The [renderAppender](https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/inner-blocks/README.md#renderappender) prop will allow us to solve this issue

## RenderAppender Overview

Before we talk about the solution, let briefly discuss the renderAppender prop and how it works.

Released with [WordPress. 5.3](https://wordpress.org/news/2019/11/kirk/), the `renderAppender` prop allows us to control the interface for inserting blocks into the related `<InnerBlocks/>` component.

There are two predefined appenders available in WordPress core:

1. `<InnerBlocks.DefaultBlockAppender />`
2. `<InnerBlocks.ButtonBlockAppender />`

### <InnerBlocks.DefaultBlockAppender />

As the name indicates, this is the default appender. If the `renderAppender` prop is `undefined`, then this is the appender that is used. It automatically inserts whichever block is configured as the default block via `wp.blocks.setDefaultBlockName` – which by default is the Paragraph block.

If you’ve worked in the block editor at all you’ve already seen this.

![](https://i2.wp.com/ryanwelcher.com/backstage/wp-content/uploads/default-block-appender.png?resize=525%2C64&ssl=1)<figcaption>Look familiar?</figcaption>

So when working with `<InnerBlocks/>`, you don’t need to pass anything to `renderAppender` to get this style of appender. If fact, you can leave it off entirely.

```
<InnerBlocks />
```

### <InnerBlocks.ButtonBlockAppender />

This appender is displayed as a + ( plus ) icon button that, when clicked, displays the block inserter. This appender does not insert a default block.

This appender is seen in the Group or Columns block.

![](https://i1.wp.com/ryanwelcher.com/backstage/wp-content/uploads/button-block-appender.png?resize=525%2C89&ssl=1)<figcaption>Groups and Column blocks use InnerBlocks.ButtonBlockAppender</figcaption>

To use this in your <`InnerBlocks`/>, you have to pass a function to `renderAppender` that returns the `<InnerBlocks.ButtonBlockAppender />` component.

```
<InnerBlocks
    renderAppender={ () => (
        <InnerBlocks.ButtonBlockAppender />
     ) }
/>
```

### No appender at all

The last option is to pass `false` to `renderAppender` to not display any appender at all.

```
<InnerBlocks
    renderAppender={false}
/>
```

## Solution

Now that we have an understanding of how the `renderAppender` prop works, let us use it to solve the problems of limiting the number of blocks allowed.

After some experimentation, the actual solution is fairly straight forward, we just need a way to count how many blocks have been inserted and if it’s more than we want, we set `renderAppender` to `false` so that nothing is displayed and the user cannot insert any more blocks until one is removed.

The `core/block-editor` datastore provides a `getBlock() `selector that we can use to get the information we need. We pass it the `clientId` of our block and we can get the list of `innerBlocks`, count them, and either display the appender or return false.

Below is the code that you would place into the `edit` property of a block, it’s very simple and but demonstrates the the solution.

```
import { useSelect } from '@wordpress/data';
import { InnerBlocks } from '@wordpress/block-editor';

const InnerBlockWithLimit = ( props ) => {
	const { clientId } = props;
	const innerBlockCount = useSelect( ( select ) => select( 'core/block-editor' ).getBlock( clientId ).innerBlocks );

	const appenderToUse = () => {
		if ( innerBlockCount.length < 10 ) {
			return (
				<InnerBlocks.ButtonBlockAppender/>
			);
		} else {
			return false;
		}
	}

	return (
		<InnerBlocks
			renderAppender={ () => appenderToUse() }
		/>
	)
}
```

Have you seen any other issues when working with `<InnerBlocks/>` or want to discuss this approach? If so, leave a comment below!

The post [Limiting the block count for InnerBlocks](https://ryanwelcher.com/2020/10/limiting-the-block-count-for-innerblocks/) appeared first on [Ryan Welcher](https://ryanwelcher.com).