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
@ida@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
@idURI (č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
httpahttpsv@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
@iddané entity (např. detail produktu, detail článku). - Vyhněte se záměně
httpvs.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
@idhttps://www.example.com/#organization - WebSite s
@idhttps://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
@idrovným kanonické URL +#webpage. - Propojte WebPage na hlavní entitu přes
"mainEntity": {"@id": "…#product"}resp.#article. - Uveďte
inLanguage,datePublished/dateModified,breadcrumbpřes@idna 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
hasVariants vlastními@idpro 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,mpnabrand. - 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
@idpouží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
- Jeden
@id= jedna entita: pokud modul potřebuje entitu, která již existuje, používá její@id– nikdy nevytváří kopii se stejnými vlastnostmi. - Deterministické generování
@id: tvorba identifikátoru musí být čistá funkce (z URL, SKU, slug); žádné náhodné hashe v produkci. - Eliminace duplicitních skriptů: místo mnoha skriptů z komponent vytvořte jeden agregovaný skript v šabloně.
- Normalizace URL: jednotná schéma (https), trailing slash politika, malá písmena v hostu, kanonické cesty.
- Referencování multimédií: obrázky a videa mají vlastní
@ida jsou referencována, nikoli kopírována. - „Parent vs. child“ model: u variant používajte
hasVariantnebo 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:
- Indexujte entity podle
@id.
<