Cara Menghindari Duplicate JSON-LD dari Theme, Plugin, dan Runtime Custom

✦ GEO.OR.ID KNOWLEDGE SYSTEM

Cara Menghindari Duplicate JSON-LD dari Theme, Plugin, dan Runtime Custom

◆ FormatPost
↻ Diperbarui17 October 2026
◷ Waktu baca9 menit
✦ KonteksPanduan praktis

Kalau WordPress sudah berjalan beberapa tahun, buka source salah satu post dan cari:

`application/ld+json`

Kadang hasilnya satu.

Kadang tiga.

Kadang tujuh.

Theme mengeluarkan Organization.

SEO plugin mengeluarkan Organization + WebSite + Article.

WooCommerce mengeluarkan Product.

Breadcrumb plugin mengeluarkan BreadcrumbList.

Custom runtime mengeluarkan graph sendiri.

Page builder menambah FAQ.

Review plugin menambah AggregateRating.

Secara individual, masing-masing merasa sedang membantu.

Secara keseluruhan, page bisa berubah menjadi rapat schema tanpa moderator.

Duplicate JSON-LD bukan semata masalah “ada dua script”.

Google general structured-data guidelines jelas bahwa multiple structured-data items pada satu page dapat dipahami, baik nested maupun sebagai items terpisah. Jadi beberapa JSON-LD scripts tidak otomatis salah.

Masalah sebenarnya:

Apakah mereka mendeskripsikan entity yang sama dengan ID berbeda?

Apakah property-nya konflik?

Apakah type salah?

Apakah visible content tidak cocok?

Apakah satu plugin menulis data lama dan runtime menulis data baru?

Duplicate script adalah symptom.

Duplicate truth adalah penyakit.

Langkah Pertama: Inventory Semua Generator

Jangan langsung disable plugin.

Cari sumber.

Theme.

SEO plugin.

Commerce plugin.

Review plugin.

Event plugin.

Custom mu-plugin.

Tag manager.

JavaScript frontend.

Server-side rendering.

Page builder.

Third-party widget.

Buat table:

Generator.

Schema types.

Templates.

Priority.

Data source.

Can disable?

Owner.

Example:

Rank Math:
Organization, WebSite, Article, Breadcrumb.

Theme:
Breadcrumb.

Custom runtime:
Organization, WebPage, Article.

WooCommerce:
Product, Offer.

Now collision visible.

Without inventory, developer plays whack-a-mole.

Disable one.

Another appears.

Plugin update changes output.

Inventory first.

Hitung Nodes, Bukan Script Tags Saja

One script can contain `@graph` with 10 nodes.

Five scripts can each contain one node.

Script count doesn't tell duplication.

Extract:

`@type`.

`@id`.

name.

url.

Relationships.

Example:

Script 1:
Organization @id `https://site.id/#organization`.

Script 2:
Organization @id `https://site.id/about/#org`.

Script 3:
Organization no @id.

Same company.

Three nodes.

That's semantic duplication.

Conversely:

Script 1 Article.

Script 2 BreadcrumbList.

Different items.

No duplicate.

So audit by entity identity.

Not by number of `<script>`.

Canonical `@id` Adalah Senjata Utama

For stable site entities, define canonical IDs.

Organization:
`https://site.id/#organization`

WebSite:
`https://site.id/#website`

Person:
canonical profile URL + `#person`.

Article:
canonical article URL + `#article`.

WebPage:
canonical URL + `#webpage`.

Breadcrumb:
canonical URL + `#breadcrumb`.

Exact naming can differ.

Consistency matters.

If plugin can be configured to use IDs, align.

If not, decide whether plugin output or custom runtime owns node.

Don't allow three Organization IDs for same company.

An `@id` isn't just decorative hash.

It's graph identity.

Ownership Matrix: Satu Type, Satu Owner Utama

Create rule.

Organization:
custom core runtime.

WebSite:
SEO plugin.

Article:
SEO plugin or custom editorial runtime.

Product:
WooCommerce.

Offer:
WooCommerce.

Breadcrumb:
theme or SEO plugin, not both.

FAQ:
page content system only when real.

Review:
review system.

This doesn't mean one generator owns all schema.

It means one authoritative owner per semantic object/template.

Other modules reference.

This modular ownership prevents collision.

If custom runtime becomes authoritative for Article, disable Article schema in plugin if possible.

Do not leave both because “more is safer.”

More can be contradictory.

Theme Schema Sering Sulit Dilihat

Some themes inject:

Organization.

Person author.

Breadcrumb.

SearchAction.

BlogPosting.

Through PHP hooks.

Plugin adds same.

Custom runtime adds same.

Check rendered source, not just settings UI.

Use:

View source.

Crawler with structured-data extraction.

Schema validator.

Browser devtools.

Server response.

Some JSON-LD may be injected client-side.

Google can render JavaScript, but debugging becomes more complex.

Know where output originates.

Search plugin files if necessary.

Do not assume “theme doesn't have schema” because settings lack option.

Plugin Schema Bisa Berubah setelah Update

SEO plugin vX outputs one graph.

vY changes IDs.

Adds ProfilePage.

Changes author.

Now custom runtime designed around old output conflicts.

Version pin/changelog awareness.

Regression test sample pages after plugin update.

Critical pages:

Homepage.

Article.

Author.

Product.

Category/hub.

Research report.

Location.

Event.

Run schema snapshot diff.

If unexpected new Organization node appears:
alert.

Schema is code dependency.

Treat plugin update as potential schema release.

Runtime Custom Harus Tahu Apa yang Sudah Ada

Custom code often just prints JSON-LD in `wp_head`.

It doesn't check plugin.

Now duplicate.

Better custom runtime:

Option A:
Disable overlapping plugin features intentionally.

Option B:
Hook into plugin graph/filter and extend existing nodes.

Option C:
Only generate types plugin doesn't own.

Option B can be elegant but couples to plugin API.

Option A gives control but more maintenance.

Choose based team.

Don't inject blindly.

Custom runtime should have ownership contract.

Merging Graph Bisa Lebih Bersih, tapi Bukan Wajib

One `@graph` can centralize nodes.

Good for institutional sites.

But Google supports multiple items too.

So goal isn't “one script only.”

Goal:

One Organization identity.

One correct Article.

One Breadcrumb trail or meaningful set.

One Product representation per real product.

No conflicting facts.

If three scripts accomplish that, acceptable.

If one graph contains duplicates, bad.

Packaging secondary.

Semantics primary.

Duplicate Organization adalah Kasus Paling Umum

Homepage:

SEO plugin:
Organization name Brand X.

Theme:
Organization name PT X Indonesia.

Custom:
Organization legalName PT X Indonesia, name Brand X.

Are these same entity?

Maybe yes.

Maybe Brand and Organization distinct.

First resolve entity model.

If Brand X is commercial Brand operated by PT X:

Create Brand node and Organization node.

Don't “deduplicate” by deleting one name randomly.

Duplicate audit can reveal modeling error, not just plugin collision.

Entity truth before technical cleanup.

Duplicate Article Bisa Punya Tanggal Berbeda

SEO plugin:
dateModified = actual content update.

Theme:
dateModified = template build.

Custom:
dateModified = current date.

Now three Article objects.

One says article updated today every page load.

This can create freshness inconsistency.

Fix source-of-truth.

WordPress `post_modified` maybe source.

But if editorial updates need material-update logic, define.

Don't let theme runtime timestamp become article date.

Technical duplicate can turn into factual error.

Duplicate Breadcrumb bisa Mengungkap Taxonomy Conflict

Plugin path:
Home → Blog → Article.

Theme path:
Home → Schema → Article.

Custom:
Home → Research → Article.

Which?

Maybe article belongs Schema cluster.

Decide canonical hierarchy.

Then one breadcrumb system.

Don't merely pick plugin with cleaner code.

Information architecture decides.

Duplicate Product Lebih Sensitif karena Price dan Stock

WooCommerce Product:
Rp1.499.000, InStock.

SEO plugin Product:
Rp1.399.000, old cache.

Custom:
Rp1.499.000, OutOfStock.

Now machine receives contradictory transaction data.

Customer impact.

Commerce schema owner should be closest to product source-of-truth.

Usually commerce platform.

Avoid custom Product unless needed.

Extend official output.

Don't duplicate price.

Inventory data must have one source.

FAQ Duplicate from Page Builder dan SEO Plugin

Page visible FAQ.

Builder injects FAQPage.

SEO plugin also creates from blocks.

Two nodes, same questions.

If content identical, redundancy.

If one excludes question, conflict.

Also remember current Google feature support can change.

Don't keep FAQ markup because legacy checklist.

Audit need.

One owner.

If not needed, remove.

Markup maintenance has cost.

Reviews Duplicate Bisa Menjadi Policy Risk

Review plugin outputs rating.

Theme outputs aggregate.

Custom schema modifies count.

If values differ, suspicious.

Google structured-data policies require markup to represent visible content and genuine user data for supported review experiences.

Do not merge by averaging.

Find actual review database.

One value.

One owner.

Manual hardcoded rating should go.

Duplicate audit is trust audit.

`@id` Conflict vs Duplicate `@id`

Two nodes same @id but different name.

This isn't two entities.

It's conflicting definitions of one entity.

Potentially worse.

Example:

`#organization`

Node 1:
name = Brand A.

Node 2:
name = Brand B.

Which?

Assembler should detect conflict.

If using separate scripts, build crawler that groups by @id and compares properties.

Same ID + compatible properties can be merged conceptually.

Same ID + incompatible property is red flag.

Don't silently last-write-wins in custom graph.

Conflict should fail QA.

No `@id` Juga Bikin Sulit

Plugin outputs Organization without ID.

Every page creates anonymous Organization.

System may still infer by same properties, but graph identity less controlled.

For large site, stable @id is useful.

If plugin cannot set, consider custom ownership.

But don't rewrite only because “anonymous nodes bad” if site small and output otherwise correct.

Prioritize actual conflicts.

Scale determines need.

How to Build Duplicate JSON-LD Audit

For every representative URL:

1. Fetch rendered HTML.
2. Extract all JSON-LD.
3. Parse JSON.
4. Flatten `@graph`.
5. List types.
6. Group by `@id`.
7. Detect same-type similar entities without same ID.
8. Compare properties.
9. Compare visible page.
10. Record generator source.

Output table:

URL.
Node type.
@id.
Name.
Generator.
Conflict.
Action.

Then pattern.

If 500 posts have same collision, fix template.

Don't manually edit posts.

Root cause.

Needle-in-haystack becomes system issue.

Detect Generator Source

JSON-LD itself may not identify plugin.

Methods:

Unique IDs/patterns.

HTML comments.

Plugin source search.

Disable on staging one by one.

WordPress hooks.

Filter names.

Script position.

Known schema signatures.

Do on staging.

Don't debug production by turning plugins off live randomly.

Safety.

Document.

Once identified, assign owner.

Use staging snapshots.

Disable vs Filter vs Extend

Disable:
Best if custom runtime fully replaces output.

Filter:
Best if plugin is good but needs ID/property correction.

Extend:
Best if plugin owns core and custom adds relationship/types.

Choose minimal intervention.

Don't copy entire plugin schema into custom code if only one property missing.

Updates become maintenance burden.

Likewise don't keep bad plugin output because disabling feels scary.

Architecture decision.

Runtime Custom Should Be Versioned

File:

schema-runtime-v3.2.php.

Changelog.

Checksum.

Feature flags.

Rollback.

Dry-run/diagnostic endpoint if project standard.

Don't edit live random snippet.

Schema may not break page visually, so errors can go unnoticed.

Versioning helps.

After deployment:

Validate sample.

Crawl.

Compare.

Search Console.

No fatal.

No duplicate.

Custom schema is software.

Treat it as such.

Don't Use Regex to Merge JSON-LD

Temptation:

Find script text.

String replace.

Danger.

JSON structure.

Escaping.

Nested graphs.

Multiple plugins.

Better use generator hooks/API or build authoritative output.

Regex may corrupt.

If runtime must remove known script:
target safe hook/filter.

WordPress enqueue/hooks.

Plugin docs.

Technical reliability matters.

Duplicate Schema Tidak Selalu Perlu Dihapus Total

Page can legitimately have:

Article.

BreadcrumbList.

VideoObject.

Organization.

Person.

WebPage.

Multiple items supported.

So don't simplify to one type.

Deduplicate entities, not meaning.

A page is rich because multiple real things exist.

The question:

Are they distinct real objects?

Are relationships correct?

Are all visible/relevant?

If yes, keep.

Over-cleaning can remove useful schema.

Diagnosis before deletion.

Duplicate Pages vs Duplicate JSON-LD

Google general structured-data guidelines note that if duplicate pages exist for same content, putting the same structured data on duplicate pages is recommended.

This is different issue.

Two URLs duplicate:
structured data can match.

One URL with conflicting duplicate nodes:
problem.

Don't confuse.

Canonicalization handles duplicate URLs.

Schema ownership handles duplicate node generation.

Different layers.

AI Search Angle: Jangan Klaim Cleanup Pasti Meningkatkan Citation

Removing conflicting JSON-LD improves information consistency.

That is controlled benefit.

Will ChatGPT cite more?

Unknown.

Will Google AI Mode mention brand more?

Not guaranteed.

Could improve entity clarity for systems consuming structured data directly/indirectly.

But attribution difficult.

Measure:

Entity accuracy.

Citation.

Source URL.

Before/after.

Keep claim bounded.

Schema cleanup is hygiene.

Not AI hack.

Regression Test yang Worth It

After every:

Theme update.

SEO plugin update.

Commerce update.

Custom runtime update.

Rebrand.

Site migration.

Check 20 sample URLs.

Automate if possible.

Assertions:

Exactly one canonical Organization ID.

No conflicting WebSite.

Article author exists.

Publisher ID correct.

Breadcrumb path valid.

Product price matches page.

No stale LocalBusiness.

No fake AggregateRating.

This catches drift early.

Schema QA should be part of deployment.

Not yearly audit.

A Clean Page Doesn't Need One Script

The goal isn't:

“Only one JSON-LD script.”

The goal:

Every node tells same reality.

Organization has one identity.

Brand separate if needed.

Article has one canonical work identity.

Product data current.

Breadcrumb path clear.

Multiple legitimate objects linked with stable IDs.

No plugin inventing alternate universe.

If one graph achieves:
great.

If three modules achieve:
also fine.

The mess begins when no one knows who owns truth.

Theme thinks it does.

Plugin thinks it does.

Runtime thinks it does.

Duplicate JSON-LD is usually an organizational problem expressed as code.

Fix ownership.

Fix IDs.

Fix source-of-truth.

Then script count becomes boring.

That's exactly where schema architecture should end up.

Leave a Comment

Your email address will not be published. Required fields are marked *