JSON-LD: osvědčené postupy pro modulární architekturu a deduplikaci

JSON-LD best practices: moduly a deduplikace

JSON-LD je preferovaný formát pro strukturovaná data na webu, protože odděluje datovou vrstvu od prezentace, snižuje křehkost HTML a usnadňuje správu. Při škálování na desítky typů stránek a stovky atributů však rychle narazíte na problémy s duplicitou entit, nekonzistentními identifikátory a „rozpletenými“ skripty. Tento článek nabízí praktický rámec, jak navrhovat modulární architekturu JSON-LD a jak spolehlivě řešit deduplikaci napříč komponentami, šablonami a celým webem.

Základní principy: entity, graf a identita

  • Entita je jakýkoli „věcný“ objekt (produkt, článek, organizace, obchod, událost), který by měl mít @id a @type.
  • Graf (@graph) je kolekce propojených entit v jednom skriptu. Umožňuje publikovat více typů najednou bez nadbytečných skriptů.
  • Identita spočívá ve stabilním, kanonickém @id URI (často URL). Stejné @id = stejná entita, ať ji publikuje kterýkoli modul.

Modulární architektura: od „monolitu“ ke stavebnici

Monolitický skript rychle roste a stává se neudržitelným. Lepší přístup je rozdělit data do modulů podle typu entity a odpovědnosti:

  • Core moduly: Organization, WebSite, WebPage – přítomné téměř všude.
  • Doménové moduly: Product, Article, BreadcrumbList, FAQPage, Offer, AggregateRating, Event, atd.
  • Kontextové moduly: LocalBusiness (na pobočkách), PostalAddress, OpeningHoursSpecification, ImageObject, VideoObject.

Každý modul generuje svou entitu/ entity s @id a odkazuje na jiné entity pomocí jejich @id. Na stránce pak tyto moduly komponujeme do jednoho @graph.

Řízení @context a verzování schémat

  • Preferujte "@context": "https://schema.org" na úrovni celého skriptu (@graph), nikoli v každé entitě zvlášť.
  • Nezaměňujte http a https v @context; používejte konzistentně https.
  • Při přechodu na nové vlastnosti udržujte zpětnou kompatibilitu a testujte, zda validační nástroje nevygenerují varování.

Stabilní identifikátory: základ deduplikace

Nejčastější příčina duplikátů je nekonzistentní nebo chybějící @id. Doporučení:

  • Každá entita musí mít stálý @id (ideálně kanonická URL), např. "@id": "https://www.example.com/#organization".
  • Produkty a články používají své kanonické URL: https://www.example.com/produkt/sku-123/, doplněné o fragment pro jednoznačnost: #product, #article, #image.
  • Opakované použití téže entity (logo, organizace, vydavatel) vždy odkazem přes "@id": "…#organization", nikoli opětovným zápisem celé entity.

Kanonikalizace a konzistence URL

  • Kanonická stránka = zdroj pravdy pro @id dané entity (např. detail produktu, detail článku).
  • Vyhněte se záměně http vs. https, trailing slash vs. bez, subdomény vs. hlavní doména – malé rozdíly vytvářejí „nové“ entity.
  • Při jazykových mutacích používejte jazykově specifické kanonické URL pro obsahové entity (článek, produkt) a pro globální entity (Organization) používejte jazykově agnostické @id (např. root domény s #organization).

Jeden skript, více entit: proč používat @graph

Místo více <script type="application/ld+json"> rozptýlených po stránce je robustnější připravit jeden skript s @graph, který agreguje všechny moduly. Minimalizujete riziko konfliktů, urychlíte parsování a máte centrální kontrolu deduplikace.

Kompozice modulů v praxi

Typická sestava pro produktový detail agregovaná do jednoho skriptu:

  • Organization (globální modul) s @id https://www.example.com/#organization
  • WebSite s @id https://www.example.com/#website
  • WebPage pro konkrétní URL stránky
  • BreadcrumbList
  • Product + Offer + AggregateRating (pokud relevantní)
  • Případné FAQPage, ImageObject, VideoObject

Modul „Organization“: single source of truth

Udržujte pouze jeden autoritativní popis organizace. Všechny ostatní moduly referencují "publisher": {"@id": "https://www.example.com/#organization"} nebo "brand": {"@id": "…#organization"}. Logo, sociální profily (sameAs) i kontaktní údaje patří sem.

Modul „WebSite“ a interní vyhledávání

Pro WebSite používejte "potentialAction": {"@type":"SearchAction"…} pouze jednou. Opakované vkládání stejného SearchAction z více modulů způsobuje duplicitu. Referencujte ho přes @id, pokud ho potřebujete použít jinde.

Modul „WebPage“: kontext pro ostatní entity

  • Každá stránka má svou entitu WebPage s @id rovným kanonické URL + #webpage.
  • Propojte WebPage na hlavní entitu přes "mainEntity": {"@id": "…#product"} resp. #article.
  • Uveďte inLanguage, datePublished/dateModified, breadcrumb přes @id na BreadcrumbList.

Produkt, nabídky a varianty: eliminace duplicitních entit

Nejčastější deduplikace se týká produktů:

  • Stejný produkt, více variant (barva/velikost): modelujte jeden Product s Offer pro dostupné varianty, nebo používejte hasVariant s vlastními @id pro varianty pouze pokud mají vlastní kanonické URL.
  • SKU vs. parent: pokud parent nemá URL, nepoužívejte ho jako samostatnou entitu; udržujte konzistentní sku, gtin, mpn a brand.
  • Cena a dostupnost: aktualizujte přes server nebo důvěryhodný feed; zabráníte divergenci mezi moduly.

BreadcrumbList, FAQPage a další „sekundární“ moduly

  • BreadcrumbList: pouze jeden na stránce; vzniká-li z více komponent, agregujte položky do jednoho objektu s deterministickou position.
  • FAQPage: každou otázku (Question) identifikujte @id (např. #faq-q1) a odpovědi (Answer) #faq-a1. Opakované otázky odkazujte přes @id, ne duplikováním textu.
  • ImageObject/VideoObject: obrázky/videa s vlastním @id používejte napříč moduly přes referenci.

Agregace do jednoho skriptu: recommended pattern

Z hlediska deduplikace je ideální skládat moduly v aplikační vrstvě a na stránku vypsat jeden skript s @graph. Příklad (schematicky):

Deduplikace: pravidla a kontrolní body

  1. Jeden @id = jedna entita: pokud modul potřebuje entitu, která již existuje, používá její @id – nikdy nevytváří kopii se stejnými vlastnostmi.
  2. Deterministické generování @id: tvorba identifikátoru musí být čistá funkce (z URL, SKU, slug); žádné náhodné hashe v produkci.
  3. Eliminace duplicitních skriptů: místo mnoha skriptů z komponent vytvořte jeden agregovaný skript v šabloně.
  4. Normalizace URL: jednotná schéma (https), trailing slash politika, malá písmena v hostu, kanonické cesty.
  5. Referencování multimédií: obrázky a videa mají vlastní @id a jsou referencována, nikoli kopírována.
  6. „Parent vs. child“ model: u variant používajte hasVariant nebo Offer podle URL modelu, vyhněte se paralelním popisům stejných SKU.

Server-side render (SSR) vs. client-side inject (CSR/GTM)

  • Preferujte SSR nebo build-time generování (SSG). Minimalizujete zpoždění a riziko, že validátory neuvidí data.
  • Pokud používáte GTM, mějte dedikovanou datovou vrstvu s jednoznačnými klíči; na jedné stránce spouštějte pouze jeden JSON-LD inject.
  • Vyhněte se souběžnému SSR + GTM generování stejných entit – vznikají duplicity a konflikty.

Řízení verzí a migrace schémat

  • Při přidávání nových vlastností nejprve nasazujte na malou vzorku, sledujte varování a dopad na zobrazení (např. bohaté výsledky).
  • Při odstraňování legacy vlastností nejprve zajistěte, aby je žádný modul již nereferencoval.
  • Verzujte generátory modulů (např. product@2.1.0) a udržujte changelog.

Validace, monitoring a alerting

  • Automatizujte validaci během CI/CD (lintování JSON, kontrola kolizí @id, přítomnosti @graph).
  • Logujte a zobrazujte na dashboardu počty entit na URL, rozdělené podle @type; náhlý nárůst signalizuje duplicitu.
  • Pravidelně kontrolujte bohaté výsledky a jejich kolísavost – náhlé ztráty často souvisejí s chybami v JSON-LD.

Deterministická skladba: „merge“ pravidla

Pokud moduly vznikají v různých vrstvách (CMS, API, microfrontend), potřebujete deterministický „merge“ algoritmus:

  1. Indexujte entity podle @id.
  2. <