Filter Hook since 0.71
the_content
Filters post content before display
Description
the_content is the last chance to change post HTML before it reaches the template. Always return the string — filters that echo will break the page.
When it runs
When the_content() runs in a template. Default callbacks handle shortcodes and embeds by priority.
Signature
apply_filters( 'the_content', string $content );Parameters
$contentstring — Post content HTML.
Examples
Basic
add_filter( 'the_content', function( $content ) {
if ( is_single() ) {
$content .= '<p><strong>Thanks for reading!</strong></p>';
}
return $content;
} );Append a note on single posts. The original HTML is returned.
Real case
add_filter( 'the_content', function( $content ) {
if ( has_shortcode( $content, 'gallery' ) ) {
$content = '<div class="has-gallery">' . $content . '</div>';
}
return $content;
} );Wrap posts that already contain a gallery shortcode.
Edge case
add_filter( 'the_content', function( $content ) {
if ( is_admin() || wp_is_json_request() ) {
return $content;
}
return $content;
} );REST and admin can also run this filter — gate side effects.
Common Use Cases
- Append/prepend content to posts
- Transform shortcodes manually
- Add schema markup to content
- Strip or sanitize specific HTML
Common mistakes
- Forgetting to return $content
- Assuming $content is always plain HTML — block-editor posts include HTML comments like <!-- wp:paragraph --> around each block, which breaks naive string matching/regex written for classic-editor content.
Related hooks
FAQ
Why did my content disappear?
A the_content callback must return the string. Echoing instead of returning wipes the post body.
Why does the_content contain HTML comments like <!-- wp:paragraph -->?
Those are block delimiters the block editor saves into post_content. Each one already passed through the render_block filter before reaching the_content, so by the time your filter runs it's rendered HTML with block comments still attached — not raw block JSON.
Source: wp-includes/post-template.php