ServicesAI Audit
← Back to Blog

Stop Yoast Adding Duplicate Schema When Using a Custom JSON-LD Plugin

Schema MarkupYoast SEOJSON-LDWordPress SEODuplicate SchemaAI VisibilityStructured Data
A close-up of a hand holding a JSON logo sticker outdoors, blurred background.

Why Yoast and Custom JSON-LD Plugins Clash

Yoast SEO outputs a fairly large Schema graph by default. Every page gets a WebPage node, every post gets an Article node, and the whole site gets an Organization or Person node depending on how you've configured it. That's fine when Yoast is the only thing managing your structured data.

The problem starts when you add a second plugin - something like a custom JSON-LD injector, a product schema tool, or a hand-rolled solution you've dropped into your theme's functions.php. Now you potentially have two blocks of structured data describing the same thing. Google sees two Organization entries for the same site, or two Article blocks for the same post. AI search engines like Perplexity and ChatGPT, which rely heavily on clean, unambiguous structured data, can get confused by this or simply ignore both.

Duplicate schema isn't just a technical annoyance. It actively undermines the signal you're trying to send. If you want AI systems to understand and cite your content, contradictory or repeated schema blocks are counterproductive.

Identifying What's Actually Duplicated

Before you start disabling things, figure out exactly what's overlapping. There's no point turning off Yoast's entire schema output if only one node is causing the conflict.

The quickest way to check is Google's Rich Results Test or Schema.org's validator at validator.schema.org. Paste your page URL and look at the raw output. You're looking for:

  • Two or more @type blocks of the same kind (e.g. two Article entries)
  • Conflicting @id values for the same entity
  • The same property (like name or url) appearing with different values across two blocks

Also check your page source directly. Search for application/ld+json and count how many script blocks appear. If you see more than one, note what each one contains before you do anything else.

The Three Main Fixes

1. Disable Yoast's Schema Output Entirely (When Your Custom Plugin Covers Everything)

If your custom JSON-LD plugin is generating all the schema you need - Organisation, WebSite, WebPage, Article, Product, the lot - then the cleanest fix is to switch Yoast's output off entirely. You keep Yoast for its title tags, meta descriptions, and sitemap features, and let your custom plugin own the schema layer.

Add this to your theme's functions.php or a site-specific plugin:

add_filter( 'wpseo_json_ld_output', '__return_false' );

This tells Yoast to produce no JSON-LD whatsoever. Clean and simple. The downside is that Yoast's schema graph is quite well-structured, so only go this route if your custom solution genuinely replicates what Yoast was doing well.

2. Remove Specific Yoast Schema Pieces (The Surgical Option)

If you only want to remove certain node types from Yoast's output rather than the entire graph, Yoast provides filters for that. Since Yoast 14.0, the schema system is built around "pieces" - individual generators for each schema type.

Here's how to remove specific pieces:

add_filter( 'wpseo_schema_graph_pieces', function( $pieces, $context ) {
    return array_filter( $pieces, function( $piece ) {
        return ! ( $piece instanceof Yoast\WP\SEO\Generators\Schema\Article );
    } );
}, 11, 2 );

In the example above, the Article piece is stripped out, leaving everything else intact. You'd swap Article for whatever class is conflicting. Common ones include:

  • Yoast\WP\SEO\Generators\Schema\Organization
  • Yoast\WP\SEO\Generators\Schema\WebPage
  • Yoast\WP\SEO\Generators\Schema\Person
  • Yoast\WP\SEO\Generators\Schema\BreadcrumbList

This approach lets you keep Yoast's breadcrumb schema or WebSite schema (both of which it handles well) while handing control of the content-level types to your custom plugin.

3. Modify Your Custom Plugin's Output to Complement Yoast

Sometimes the better answer isn't to strip Yoast but to adjust what your custom plugin outputs so the two don't conflict. If Yoast is already producing a solid WebPage node, your custom plugin doesn't need to output one too. It can focus on supplementary types - FAQPage, Product, HowTo - that Yoast doesn't generate by default.

This is often the most practical path if you're using something like a hand-coded JSON-LD block for a specific page type. Scope it narrowly. Only output the schema types your custom plugin is actually good at.

Handling the @id Graph Problem

Yoast uses a linked graph structure with @id references. For example, the Article node references the WebPage node via its @id, which in turn references the WebSite node. It's elegant when it works.

If your custom JSON-LD plugin outputs a standalone Article block without referencing Yoast's WebPage @id, you end up with two disconnected schema graphs on the same page. Search engines and AI systems handle connected graphs much better than a pile of isolated schema blobs.

If you're keeping both Yoast and a custom plugin, aim to make them part of the same graph. Your custom schema can reference Yoast's @id values. Yoast's WebPage @id typically follows the pattern https://yoursite.com/page-url/#webpage. You can hardcode this into your custom JSON-LD or retrieve it dynamically using Yoast's PHP functions.

For most WordPress sites, though, the cleanest solution is simply to pick one system and let it own the schema layer. Mixing two graphs is genuinely complex to get right.

What This Means for AI Search Visibility

Structured data is one of the primary ways AI search engines like ChatGPT and Perplexity extract reliable, structured information about your site. When they encounter duplicate or conflicting schema, a few things can happen: they might pick one block and ignore the other, they might merge properties in unpredictable ways, or they might discount the structured data entirely and fall back on raw content parsing.

None of those outcomes are ideal. Clean, accurate, well-formed schema gives AI models a clear signal about what your page is, who created it, and what it contains. That's exactly what drives citations and recommendations in AI-generated answers.

At FlinnSchema, this is one of the most common issues we encounter during audits: sites with Yoast running alongside a secondary plugin, both fighting over the same schema territory. The fix is rarely dramatic, but it requires knowing which pieces Yoast handles well and which are better delegated elsewhere.

If you want to see exactly what your current schema output looks like from an AI readability perspective, the free AI visibility audit runs through this kind of structured data conflict as part of the review.

A Practical Decision Framework

Here's a simple way to decide which approach to take:

  • Custom plugin covers everything? Disable Yoast's schema output with the filter above. Keep Yoast for everything else.
  • Conflict is limited to one or two types? Use the wpseo_schema_graph_pieces filter to remove only those pieces from Yoast.
  • Custom plugin only handles specific page types? Narrow its output. Let Yoast handle the global graph and add your custom schema as supplementary nodes.
  • Not sure what's conflicting? Run the validator first. Don't guess.

One more thing worth noting: if you're using Yoast Premium, the schema editor gives you more granular control over individual properties. You might find you don't need a second plugin at all if Yoast Premium's controls are flexible enough for your use case.

Testing After You Make Changes

After any change to schema output, always validate. Use at least two of these:

  • Google's Rich Results Test (search.google.com/test/rich-results) - shows which rich result types are detected
  • Schema.org Validator (validator.schema.org) - shows the full parsed graph, including @id connections
  • View source - search for application/ld+json and manually verify the count and content

Give Google Search Console a few days after any changes and check the Rich Results report for any new warnings or errors. A sudden drop in detected rich results often signals that a change broke the graph somewhere.

For posts and articles specifically, check whether the Article or BlogPosting type is still being detected correctly. AI search engines pay particular attention to article-level schema because it helps them understand authorship and content freshness - two factors that affect whether content gets cited in AI answers.

You can read more about getting article schema right in our post on using Article schema to get your blog posts cited by AI.

For a broader look at how Yoast's default schema performs in AI search contexts, it's also worth checking our analysis of whether Yoast SEO adds the right schema for AI search visibility.

Frequently Asked Questions

Will disabling Yoast's schema output affect my Google rankings?

Not directly. Yoast's schema output is one signal among many, and Google has never confirmed it as a direct ranking factor. What it does affect is your eligibility for rich results. If you're disabling Yoast's schema in favour of a custom plugin that covers the same types, you should see no meaningful change in rich result eligibility - provided your custom output is correctly formatted and covers the same node types. Always validate after making the change.

How do I know which schema types Yoast is generating on a given page?

The easiest way is to view the page source and search for application/ld+json. You'll see Yoast's graph as a single JSON-LD block containing multiple @graph nodes. Each node has a @type property that tells you what it is. Alternatively, paste the URL into the Schema.org Validator and it will parse and label every node for you.

Can I use the wpseo_schema_graph_pieces filter in a child theme?

Yes. You can add the filter to your child theme's functions.php, which is the safest place for it since child theme files aren't overwritten by theme updates. You could also place it in a small site-specific plugin, which is arguably cleaner because it keeps your schema logic separate from your theme entirely.

Does duplicate schema actually hurt AI visibility, or is it just a theoretical problem?

It's a real problem, not just a theoretical one. AI language models that process web content for citations rely on structured data to resolve entity information quickly and confidently. Contradictory schema - two Organization blocks with different name values, for instance - creates ambiguity. The model may discard both in favour of content it can interpret more cleanly. In practice, sites with clean, single-source schema tend to perform better in AI-generated answer citations than those with messy or conflicting output.

Want to check your AI visibility?

Run a free audit on your website and see how visible you are to ChatGPT, Perplexity, and other AI search engines.

Run Free Audit