Adding structured data to a WordPress post, nine times out of ten, doesn't mean writing new code. It means reading the JSON-LD your SEO plugin already generates, working out which properties are missing or wrong and filling them in at the right point, without creating a second block that contradicts the first.
Most guides on this start from scratch: what Schema.org is, a list of plugins, code to copy and paste. But WordPress runs 40.1% of all websites according to W3Techs (figure for October 2026, worldwide), Yoast SEO reports more than 10 million active installations and Rank Math more than 4 million. If you've opened this page you almost certainly have a graph running already, and the real job is fixing it.
To see where people usually go wrong, on 10 October 2026 I read the markup of the pages on the first page of Google UK for the searches about adding structured data to WordPress. The results are in the table further down, and they say more than any list of tips.
Before you add anything, look at what's already there
The check takes two minutes. Open a published post, view the page source and search for application/ld+json. If you use Yoast you'll find a block with the class yoast-schema-graph, with Rank Math one with rank-math-schema, with All in One SEO one with aioseo-schema. Inside there's an @graph: a list of nodes linked to each other through @id, usually Organization, WebSite, WebPage, Article, BreadcrumbList and Person.
If there are two or more ld+json blocks, ask where each one comes from. The usual sources of a second block are the theme, a reviews plugin, a page builder, or a tag added years ago in Google Tag Manager. Two blocks aren't a mistake in themselves: Google's general guidelines accept both nested items and separate items, and recommend @id to link them. The trouble starts when two sources describe the same thing differently, for example two Organizations with different names or two Articles with different authors.
There are two free tools for reading the graph without decoding the JSON by hand. Google's Rich Results Test tells you whether the page is eligible for a supported rich result. The Schema Markup Validator shows every node, including the ones Google doesn't turn into anything visible. For a blog post you mostly need the second, because Article doesn't produce a dedicated rich result and the Rich Results Test tends to say very little.
What's in the markup of the top-ranking guides
I took the organic results on the first page of Google UK for "wordpress schema markup", "how to add structured data to wordpress" and "structured data wordpress", removed the results that aren't articles (videos, forums, plugin pages, a help centre guide) and downloaded the 13 URLs left. All 13 responded, and I analysed each one by extracting every JSON-LD block and counting types, article properties and author nodes.
| What I checked | Result |
|---|---|
| Pages with at least one JSON-LD block | 13 of 13 |
| Pages with an Article, BlogPosting or NewsArticle node | 12 of 13 |
| Plugin generating the graph | Yoast 5, Rank Math 3, AIOSEO 1, none of the three 4 |
| Articles with dateModified | 11 of 12 |
| Articles with the image property | 11 of 12 |
| Author with a URL that identifies them | 8 of 12 |
| Author with at least one profile in sameAs | 6 of 12 |
| Pages still declaring FAQPage | 2 of 13 |
| Pages still declaring HowTo | 0 of 13 |
| Content anomalies in the markup | 4 cases, one per page (described below) |
The technical side, the part a plugin does on its own, is almost always fine: dates, image, breadcrumbs. The four anomalies have nothing technical about them. A 2022 guide carries a second block, from an analytics plugin, that marks it as a NewsArticle, in other words as news, next to the BlogPosting from the SEO plugin. One site declares as author a Person with no name, linked to a generic author archive with no slug. Another puts the author's social media handle inside the name. The fourth names one person as the author while the URL, photo and profiles in the same node belong to a different writer.
These are set-up mistakes, not code mistakes: no validator flags them, because the JSON is syntactically correct. That's also why the check has to be done by eye and not only with the tool.
The Article properties that matter on a blog
Google's documentation on Article markup, updated on 8 September 2026, has a feature that surprises anyone coming from the tutorials: there are no required properties. Google says to add the ones that apply to your content. There are seven recommended ones, and on WordPress each takes its value from a specific place.
| Property | What Google asks for | Where WordPress gets it |
|---|---|---|
| headline | The title of the article | Post title |
| image | Indexable images, at least 50,000 pixels (width times height), aspect ratios 16:9, 4:3 or 1:1 | Featured image |
| datePublished | Date first published, in ISO 8601 format | Post date |
| dateModified | Date last modified, in ISO 8601 format | Post last-modified date |
| author | The person or organisation that wrote the article | WordPress user assigned as author |
| author.name | The name only, without titles, prefixes or suffixes | Display name in the user profile |
| author.url | A page that uniquely identifies the author | Author archive, if enabled |
Three of these seven break without anyone noticing. The image is missing when the post has no featured image: that's the one case in the previous table without image, and the advice on sizes is in our guide to image optimisation for SEO. dateModified updates even when you fix a comma: on one of the pages analysed, a guide first published in 2020, the markup declares a modification in March 2026, while the text still tells you to use Google's Structured Data Testing Tool, which Google has since retired, and never names the Rich Results Test. The date is the date of the last save, not the last review. Finally, the author's name goes into the markup exactly as it's written in the Display name field of the profile, so "Dr Jane Smith, SEO Specialist" goes against Google's instruction to give the name only.
The author is the part plugins leave half done
The Person node is what tells Google who wrote the piece, and it's the most direct link between the markup and E-E-A-T. In the 12 articles with an Article node, 4 authors have no URL that identifies them and 6 have no profile linked in sameAs. The graph on this blog is no exception: on our article about schema markup the author is declared as the organisation and there's no Person node at all. I mention it because it's the most common gap, not the most serious one.
Google gives four instructions on the author, all on the Article page: each author goes in their own author field, never two names in the same field; the type must be Person for a person and Organization for a company; the name contains no titles; the URL leads to a page that identifies that author. There's also a dedicated type for that page, ProfilePage, which Google lists specifically for author pages on news sites and "About me" pages on blogs. Its one required property is mainEntity, the person the page is about, with their name. External profiles go in sameAs.
The author's sameAs is where the markup adds information that isn't on the page in a machine-readable form: it says that the Jane Smith on the blog is the same Jane Smith on LinkedIn. It's the same mechanism an Organization uses to get into the Knowledge Graph.
Article, BlogPosting or NewsArticle
Google's documentation is explicit: "Article objects must be based on one of the following schema.org types: Article, NewsArticle, BlogPosting". For a company blog the practical choice is between Article and BlogPosting, and it changes nothing in the results. In the pages analysed, two of the three using Rank Math declared BlogPosting and the third Article. NewsArticle only makes sense if you publish news where the date matters, like a newspaper or the news section of a listed company. On a guide that stays valid for years it's false information, small but false.
In Yoast you change the type for a single post in the Schema tab of the plugin's box, and for all posts in the content type settings. In Rank Math the same step is in the post's schema generator and in the default values for posts. Before changing it, check that no other source on the site declares a second Article.
How to add what's missing without duplicating
There are four routes, in order from the safest to the most fragile. The rule that holds them together is a single one: extend the graph that exists instead of putting another one next to it.
1. The plugin settings. This is the route that solves most of the cases in the table: organisation name and logo, default article type, author archive enabled, social fields in the user profile filled in. If you already use an SEO plugin, the comparison between the options is in our guide to SEO plugins for WordPress. Two SEO plugins active together produce two complete graphs on the same page: keep only one.
2. The plugin's filters, in PHP. Yoast has a Schema API with a filter for every node: wpseo_schema_article, wpseo_schema_person, wpseo_schema_organization, wpseo_schema_breadcrumb, wpseo_schema_webpage, plus wpseo_schema_graph_pieces to add a whole node. Here's an example that completes the author node with an external profile, to go in a custom plugin or in the child theme's functions.php:
add_filter( 'wpseo_schema_person', function ( $data ) {
$data['sameAs'] = isset( $data['sameAs'] ) ? (array) $data['sameAs'] : array();
$data['sameAs'][] = 'https://www.linkedin.com/in/author-name/';
return $data;
} );The advantage over a hand-written block is that the node stays linked to the rest of the graph through the same @id, so the Article keeps pointing to the same Person. Rank Math has similar filters in its developer documentation.
3. Google Tag Manager. Google documents this method (page updated on 10 December 2025): a custom HTML tag with the JSON-LD inside and GTM variables to read the values from the page, "instead of duplicating the information in GTM". It works, but the markup only exists after JavaScript rendering, and Google warns that on Product markup this can make Shopping crawls less frequent and less reliable. For a post the risk is lower; the fact remains that the JSON-LD lives somewhere the people running the site often don't look, and it doesn't appear in the HTML source, so the two-minute check described above won't see it.
4. An HTML block inside the post. Pasting a <script type='application/ld+json'> into a Gutenberg Custom HTML block is the route you see in tutorials. I'd advise against it for two reasons: on many sites users with the Author role aren't allowed to save script tags, and the block stays disconnected from the plugin's graph, so it creates exactly the second Article with different data that you need to avoid. The only sensible use is a type the plugin doesn't handle, on a single page.
VideoObject, FAQ and HowTo inside a post
A blog post often contains something else: a video, a questions section, a set of steps. The markup for each has had a different history in the last few years.
VideoObject is still useful: it's the type that makes the video eligible for previews and key moments, and the details are in our guide to video SEO. FAQPage no longer produces anything: Google's documentation says the FAQ rich result stopped appearing in Search from 7 May 2026. Two of the thirteen pages analysed still declare it. That isn't a mistake, Google doesn't penalise markup it doesn't use, but if you wrote FAQs only for the accordion in the results, it's worth rethinking what they're for: I go into it in the article on FAQs for SEO. HowTo hasn't produced rich results since September 2023.
On other CMSs the reasoning is the same
Shopify, Wix, Squarespace and Webflow generate part of the markup from the theme or the platform, and how much varies from theme to theme. The method doesn't change: page source, count the ld+json blocks, read them in the validator, add only what's missing. The differences on each platform, including the apps that add a second graph, are in our guides to Shopify SEO and Wix SEO. For WordPress the full picture, from markup to speed, is in the guide to WordPress SEO.
How to check the whole blog, not one page
The Rich Results Test and the Schema Markup Validator work on one URL at a time. For a blog with hundreds of posts you need two different tools. The enhancement reports in Google Search Console show errors and warnings on the types Google supports, across the whole site. Screaming Frog SEO Spider, with structured data extraction and validation switched on in the crawl configuration, returns for each URL the types found and the errors against Schema.org and Google's rules.
In the crawl export it's worth looking for three things, the same ones that came up in the analysis: pages with two nodes of the same type, posts without image, and author nodes with an empty name or a URL that doesn't identify anyone. The check is part of basic technical SEO, and it's worth repeating after every change of theme or plugin.
What not to expect from a post's markup
Article markup doesn't move your ranking. Google says as much indirectly: a manual action on structured data, according to its guidelines, removes eligibility for rich results and "doesn't affect how the page ranks in Google web search".
It doesn't increase citations in AI answers either, at least on pages that are already visible. The Ahrefs study by Louise Linehan followed 1,885 pages that added JSON-LD between August 2025 and March 2026, compared with a matched control group: +2.4% citations on Google AI Mode and +2.2% on ChatGPT, neither distinguishable from zero, and a 4.6% fall on AI Overviews, which the authors say may reflect other factors. The sample is global and limited to pages that already had more than 100 AI Overview citations a month. There's no UK-specific equivalent. The full reasoning on what markup does and doesn't do is in the article on schema markup in 2026.
What a post's markup really does is remove ambiguity about two things: who wrote it and when. If you need someone to sort out the graph along with the rest of the site, it's part of our SEO consultancy work, and for visibility in language model answers there's our SEO for AI service.
Something people rarely say: the four anomalies I found almost certainly weren't decided by whoever wrote the article. The analytics plugin that marks a guide as news, the author with no name, the handle in the name field, the author node mixing two writers: in my view they're all settings decided once, at launch or during a change of theme, and never looked at again. A blog's markup ages with migrations more than with content. That's why checking the graph belongs on the checklist for every website redesign, next to the redirects, and not in the editorial plan.
Frequently asked questions about structured data in WordPress
Not if you already use an SEO plugin. Yoast, Rank Math and All in One SEO generate Article, Person, Organization and BreadcrumbList on every post by themselves. A dedicated plugin is only needed for types your SEO plugin doesn't handle, and you should check that it doesn't generate a second Article.
No. Each one produces its own complete graph, so the same page ends up with two Organizations and two Articles, often with different data. Pick one plugin and deactivate the other.
It makes no difference. Google accepts Article, NewsArticle and BlogPosting for Article features. Only use NewsArticle for content that is news, not for guides that stay valid for years.
You don't have to. Since 7 May 2026 Google no longer shows the FAQ rich result, but markup left on the page doesn't cause problems. It's more useful to ask whether those questions still help the reader.
In the Rich Results Test for a single URL and in the Schema Markup Validator for every node, including those that don't produce rich results. For the whole site you need the Search Console enhancement reports or a Screaming Frog crawl with structured data extraction switched on.