WordPress runs the content of every post through a set of filters before outputting it with the_content(). One of those filters — wpautop — wraps blocks of text in <p> tags and adds line breaks. It is useful for simple text content, but when posts are built in the Gutenberg editor or with page builders, it often generates empty <p> </p> and <p></p> elements — invisible spacer paragraphs that add unwanted whitespace, break CSS selectors, and inflate the DOM. These empty elements also affect SEO: duplicate or near-duplicate whitespace paragraphs can confuse crawlers and make the content/code ratio worse than it needs to be. The fix is a single filter on the_content that strips empty paragraph tags after wpautop has finished, using a regex that matches paragraphs containing only whitespace or non-breaking space characters.
Problem: The Gutenberg editor or a page builder is generating empty <p></p> and <p> </p> tags in post content, adding invisible whitespace, breaking layouts, and inflating the DOM.
Solution: Add a filter on the_content that runs after wpautop and removes paragraphs containing only whitespace or entities. Use force_balance_tags() first to avoid stripping paragraphs with unclosed tags.
<?php
add_filter( 'the_content', 'remove_empty_paragraphs', 20 );
function remove_empty_paragraphs( $content ) {
// Balance any unclosed tags first to avoid removing legitimate content
$content = force_balance_tags( $content );
// Remove paragraphs that contain only whitespace or entities
return preg_replace( '/<p>(?:\s| |Â )*?<\/p>/i', '', $content );
}
If you also need to strip empty paragraphs from ACF WYSIWYG fields or widget text, apply the same function to those filters:
<?php
// ACF WYSIWYG fields
add_filter( 'acf/format_value/type=wysiwyg', 'remove_empty_paragraphs', 20 );
// Text widgets
add_filter( 'widget_text_content', 'remove_empty_paragraphs', 20 );
NOTE: The filter priority is set to 20 so it runs after wpautop (priority 10) and after most other content filters (default priority 10). If you are using a page builder that registers its own content filters at a higher priority, you may need to raise the priority further — try 99 if empty paragraphs still appear after applying the filter.