“This block contains unexpected or invalid content.”
Why It Happens
When your block is loaded in the editor, WordPress performs a check to ensure that the content generated by your block’s front-end view (known as the save function in technical terms) matches the content of the block retrieved from the database. It does this by initializing your block’s attributes based on the block’s content from the database. It then asks your block to generate its front-end output using those attributes. If the output generated by your block doesn’t match the content from the database, the message “This block contains unexpected or invalid content” will be displayed above your block.
Thankfully, WordPress emits an error message showing the content generated by your block’s front-end view (i.e. save function) and the content retrieved from the post body. To see the error, open your browser’s Developer Tools (F12 in most browsers) and click on the Console tab. You will see a message like this:
You can compare the two versions to isolate why your front-end view is outputting content that is different from the database version.
There are a few reasons why the content may not match:
- You are using an attribute source other than block meta that isn’t configured correctly
- WordPress or another plugin altered your block’s content
- The content of your block was edited directly in the database
Using an Attribute Source Other Than Block Meta That Isn’t Configured Correctly
Imagine you create a block with a single attribute named “headline”. You configure the attribute to use the “HTML” Attribute Source and enter “h1” for the selector. This means when your block is loaded in the editor, WordPress will search your block for an h1 tag and initialize your headline attribute to the content of the h1 tag.
Now imagine you add a RichText component and link it to the headline attribute. However, instead of setting the RichText’s tag name to h1 you accidentally set it to h2. When your block is saved to the database, the RichText component will generate an h2 tag and your block’s content will look something like this (assuming you typed “Hello World!” for the headline):
<div class="my-custom-block">
<h2>Hello World!</h2>
</div>
See the problem? The next time your block is loaded in the editor, WordPress will initialize your headline attribute to the content of the block’s h1 tag. But the block doesn’t have an h1 tag! So the headline attribute will be empty causing the block to output something like this:
<div class="my-custom-block">
<h2></h2>
</div>
To fix this, you either need to adjust the Selector of your headline attribute to be an h2, or change your RichText component to output the expected h1 tag.
WordPress or Another Plugin Altered Your Block’s Content
It’s possible that WordPress or another plugin is altering your block’s content. For example, WordPress may add a rel=”noopener” attribute automatically to your links for security reasons.
This can cause the output of your block’s front-end view to be different from the content saved to the database.
You need to compare the output that is being generated by your block to the content from the post body to determine the difference. To fix, you need to update your block’s output to match what is being added by WordPress or another plugin. In this example, you could fix the issue by making sure all links in your block contain the rel=”noopener” attribute.
The Content of Your Block Was Edited Directly in the Database
You may receive an invalid content error if your block’s content is changed directly in the database.
For example, imagine you include a link in your block and you hardcode the link’s URL to http://www.mysite.com (your site’s URL). Now let’s pretend you set up a staging site and a script runs to update all of your site’s URLs in the database to http://staging.mysite.com. Your block will still output the hardcoded URL (i.e. http://www.mysite.com) but the content in the database will contain a different URL (i.e. http://staging.mysite.com).
To fix this, avoid hardcoding values such as URLs into your blocks that could potentially change. Instead, use an attribute to store the value.
Avoiding Unexpected or Invalid Content Errors
Here are some suggestions to help you avoid this error.
Plan Ahead
When it comes to building blocks, a little bit of planning can go a long way. Planning how you want your block to work ahead of time minimizes the number of changes you need to make which reduces the likelihood of it breaking. Try to anticipate the structure and functionality your block will need and build it that way from the beginning.
Use the Block Meta Attribute Source
Use the block meta Attribute Source for your attributes until you feel confident using the other attribute sources. The block meta Attribute Source is the easiest to work with because it doesn’t require any additional configuration.
Test
Before using your block on hundreds of pages, try it out on one or two pages first. Make various changes and reload the page to confirm your block loads correctly.
Build a New Block
If you need to make significant changes to an existing block, consider creating a new block instead.
Use Dynamic Blocks
If you feel comfortable writing PHP, consider making your blocks dynamic. Using dynamic blocks is an easy way to avoid this error because they are not checked for invalid content (because their markup is not saved to the database).
Learn More
If you’d like to learn more about the technical details of why blocks are validated, check out this article from WP Tavern.