In templates/sections/entry-post.php, the BlogPosting structured data includes:
"articleBody": "<?php the_content(); ?>"
the_content() echoes the rendered post HTML. It does not return a string suitable for embedding in JSON. Because this runs after the normal content block (which already calls the_content()), the full post body is output a second time on single blog posts. Once in the article, and again inside (and effectively outside) the JSON-LD script.
Adverse effects:
- Duplicate content — the post body renders twice (visible to users at least in code and definitely crawlers).
- Broken JSON-LD — HTML/quotes in the body corrupt the script, so Google may ignore or flag the BlogPosting markup.
- SEO / rich-result risk — invalid or duplicate structured data can hurt eligibility for article rich results and look like thin/duplicate content.
- Side effects from filters — the_content runs a second time (shortcodes, embeds, analytics hooks), which can inflate scripts, fire tracking twice, or break layout.
Affected file:
templates/sections/entry-post.php (around the application/ld+json block)
Steps to reproduce:
- View a single blog post that has body content.
- View page source / inspect the DOM below the article.
- Observe the post content appearing again near the JSON-LD block (and/or broken JSON in the script tag).
Expected:
- Post content renders once.
- JSON-LD is valid JSON and does not re-render the post.
Actual:
- Post content appears twice.
- articleBody often produces invalid JSON (unescaped quotes, HTML tags, etc.).
Suggested fix:
Build the schema with non-echoing getters and wp_json_encode(), and avoid the_content() in the schema. Either omit articleBody, or use something like wp_strip_all_tags(get_the_content(null, false)) / get_post_field('post_content', …) if you still want a plain-text body field.
Example approach:
<script type="application/ld+json">
<?php
$schema = [
'@context' => 'https://schema.org',
'@type' => 'BlogPosting',
'headline' => wp_strip_all_tags(get_the_title()),
// ... other fields using get_* helpers ...
'mainEntityOfPage' => get_permalink(),
];
echo wp_json_encode(array_filter($schema), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
?>
</script>
In templates/sections/entry-post.php, the BlogPosting structured data includes:
"articleBody": "<?php the_content(); ?>"the_content() echoes the rendered post HTML. It does not return a string suitable for embedding in JSON. Because this runs after the normal content block (which already calls the_content()), the full post body is output a second time on single blog posts. Once in the article, and again inside (and effectively outside) the JSON-LD script.
Adverse effects:
Affected file:
templates/sections/entry-post.php (around the application/ld+json block)
Steps to reproduce:
Expected:
Actual:
Suggested fix:
Build the schema with non-echoing getters and wp_json_encode(), and avoid the_content() in the schema. Either omit articleBody, or use something like wp_strip_all_tags(get_the_content(null, false)) / get_post_field('post_content', …) if you still want a plain-text body field.
Example approach: