Implementér strukturerede data (Schema.org) i dit Shoporama-tema
Komplet guide til JSON-LD strukturerede data i et Shoporama-tema. Smarty-eksempler til Product, Store, BreadcrumbList og AggregateRating med korrekte safe-metoder.
Strukturerede data (Schema.org) hjælper Google og andre søgemaskiner med at forstå indholdet på dine sider. For en webshop er det især relevant at markere produkter, butiksinformation, brødkrummer og produktanmeldelser, så du kan opnå "rich snippets" i søgeresultaterne med fx pris, lagerstatus og stjernebedømmelse.
Tip: Shoporama tilføjer automatisk grundlæggende Schema.org-markup for produkter via vores indbyggede SEO-funktioner. Læs om automatisk struktureret data og SEO i Shoporama. Denne artikel er til dig, der vil bygge eller udvide markup'et selv i dit tema.
Hvad er strukturerede data?
Strukturerede data er en standardiseret måde at beskrive sidens indhold på i et format, søgemaskiner forstår. JSON-LD er det anbefalede format og placeres i et <script type="application/ld+json">-tag. Det påvirker ikke sidens visuelle udseende, men giver søgemaskinerne struktureret information, der kan bruges til rich snippets.
De rigtige safe-metoder på SafeProduct, SafeWebshop og SafeCompany
Inden du bygger dit eget JSON-LD-markup er det vigtigt at kende de safe-metoder, der faktisk findes på objekterne i et Shoporama-tema. Disse er de stabile metoder du kan bruge i Smarty.
På $product (SafeProduct):
- getName(), getDescription(), getOwnId(), getGtin(), getMpn(), getBrandName()
- getPrice(), getSalePrice(), getRealPrice(), getLowest30DayPrice()
- getStockCount() og getIsInStock()
- getImage() og getImages() returnerer SafeImage med getSrc($w, $h, $type)
- getAvgRating($no_round), getReviewCount(), getProductReviews($limit)
- getUrl() giver produktets relative sti
På $webshop (SafeWebshop):
- getName(), getDescription(), getCurrency(), getUrl(), getLogo()
- getCompany() returnerer SafeCompany
På $webshop->getCompany() (SafeCompany):
- getName(), getRegNr(), getEmail(), getPhone()
- getAddress(), getZipcode(), getCity(), getCountry()
Bemærk: Brug ikke $product->getStock(), $product->getAverageRating(), $webshop->getCurrencyCode(), $webshop->getDomain(), $webshop->getEmail() eller $webshop->getPhone(). De findes ikke som safe-metoder, og dit tema vil fejle. Brug i stedet getStockCount(), getAvgRating(), getCurrency(), getUrl() og getCompany()->getEmail()/getPhone().
Produkt-markup (Product)
Den vigtigste type for en webshop er Product-markup. Indsæt blokken i din produkt-template (typisk product/view.html):
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "<{$product->getName()|escape:'javascript'}>",
"description": "<{$product->getDescription()|strip_tags|escape:'javascript'}>",
"sku": "<{$product->getOwnId()|escape:'javascript'}>",
<{if $product->getGtin()}>
"gtin": "<{$product->getGtin()|escape:'javascript'}>",
<{/if}>
<{if $product->getMpn()}>
"mpn": "<{$product->getMpn()|escape:'javascript'}>",
<{/if}>
<{if $product->getBrandName()}>
"brand": {
"@type": "Brand",
"name": "<{$product->getBrandName()|escape:'javascript'}>"
},
<{/if}>
<{if $product->getImage()}>
"image": "<{$product->getImage()->getSrc(800, 800, 'fit')}>",
<{/if}>
"offers": {
"@type": "Offer",
"url": "<{$webshop->getUrl()}><{$product->getUrl()}>",
"price": "<{$product->getRealPrice()|string_format:"%.2f"}>",
"priceCurrency": "<{$webshop->getCurrency()}>",
"availability": "<{if $product->getStockCount() > 0}>https://schema.org/InStock<{else}>https://schema.org/OutOfStock<{/if}>"
}
}
</script>
Tre vigtige pointer i eksemplet:
- Pris hentes med getRealPrice(), så eventuel udsalgspris og rabat indgår, og momsen er lagt til.
- Valuta hentes med getCurrency() på $webshop (returnerer fx "DKK" eller "EUR").
- Lagerstatus afgøres med getStockCount(). Du kan også bruge getIsInStock() hvis du vil tillade salg af lagerførte produkter med 0 på lager.
Førpris (Omnibus-direktivet)
Hvis produktet er på udsalg, anbefaler Google at vise den laveste pris de seneste 30 dage som referencepris. Brug getLowest30DayPrice() til at hente den. Den returnerer null hvis der ikke er nok prishistorik.
Produktanmeldelser (AggregateRating)
Hvis du bruger Shoporamas indbyggede anmeldelsessystem, kan du tilføje en gennemsnitsbedømmelse direkte i Product-markup'et. Det kan give stjerner i Googles søgeresultater. Indsæt blokken inden i Product-objektet:
<{if $product->getReviewCount() > 0}>
,
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "<{$product->getAvgRating(true)|string_format:"%.1f"}>",
"reviewCount": "<{$product->getReviewCount()}>"
}
<{/if}>
Parameteren true til getAvgRating() giver et ikke-afrundet gennemsnit, hvilket Google foretrækker (fx 4,3 i stedet for blot 4).
Butiksinformation (Store / LocalBusiness)
Du kan også markere selve webshoppen, fx i din footer-template. Hent kontaktdata fra $webshop->getCompany(), så de oplysninger, du allerede har sat under Indstillinger, Firmaoplysninger, indgår automatisk:
<{$company = $webshop->getCompany()}>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Store",
"name": "<{$webshop->getName()|escape:'javascript'}>",
"url": "<{$webshop->getUrl()}>"
<{if $company}>
,
<{if $company->getEmail()}>
"email": "<{$company->getEmail()|escape:'javascript'}>",
<{/if}>
<{if $company->getPhone()}>
"telephone": "<{$company->getPhone()|escape:'javascript'}>",
<{/if}>
"address": {
"@type": "PostalAddress",
"streetAddress": "<{$company->getAddress()|escape:'javascript'}>",
"postalCode": "<{$company->getZipcode()|escape:'javascript'}>",
"addressLocality": "<{$company->getCity()|escape:'javascript'}>",
"addressCountry": "<{$company->getCountry()|escape:'javascript'}>"
}
<{/if}>
<{if $webshop->getLogo()}>
,
"logo": "<{$webshop->getLogo()->getSrc(400, 400, 'fit')}>"
<{/if}>
}
</script>
Sørg for at firmaoplysninger er fyldt korrekt ud i admin under Indstillinger, Firmaoplysninger. Hvis du har en fysisk butik, kan du bruge LocalBusiness eller en mere specifik subtype (fx ClothingStore) som @type.
Brødkrummer (BreadcrumbList)
På produkt- og kategorisider er det god SEO-praksis at markere brødkrummer. Eksempel for et produkt med hovedkategori:
<{if $product->getMainCategory()}>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "<{$webshop->getName()|escape:'javascript'}>",
"item": "<{$webshop->getUrl()}>"
},
{
"@type": "ListItem",
"position": 2,
"name": "<{$product->getMainCategory()->getName()|escape:'javascript'}>",
"item": "<{$webshop->getUrl()}><{$product->getMainCategory()->getUrl()}>"
},
{
"@type": "ListItem",
"position": 3,
"name": "<{$product->getName()|escape:'javascript'}>",
"item": "<{$webshop->getUrl()}><{$product->getUrl()}>"
}
]
}
</script>
<{/if}>
Test dine strukturerede data
Brug Googles og Schema.org's værktøjer til at validere dit markup, inden du går live:
- Rich Results Test tjekker om dit markup giver rich snippets i Google
- Schema Markup Validator validerer JSON-LD-syntaksen
- I Google Search Console kan du se rapporter over dine produkter og rich results, efter siderne er crawlet
Tip: Hvis du allerede har aktiveret automatisk struktureret data i Shoporama, så vær opmærksom på at undgå dubletter. Tjek hvad der allerede er på siden, inden du tilføjer dit eget markup.
Ofte stillede spørgsmål
Skal jeg overhovedet selv kode JSON-LD?
Nej, ikke nødvendigvis. Shoporama har indbygget automatisk struktureret data for produkter, og det dækker det meste. Selv-kodning er primært relevant, hvis du vil tilføje yderligere felter eller bruge en mere specifik @type, fx for hoteller, restauranter eller events.
Hvilke schema-typer kan jeg bruge ud over Product?
I et Shoporama-tema kan du bygge alle Schema.org-typer, der findes som JSON-LD. De mest brugte for webshops er Product, Offer, AggregateRating, Review, BreadcrumbList, Store, LocalBusiness, Organization, WebSite med SearchAction og FAQPage til faste FAQ-sider.
Hvorfor får jeg fejl i Rich Results Test?
De typiske fejl er manglende felter (fx price uden priceCurrency), forkert formatering af tal eller anførselstegn der ødelægger JSON-syntaksen. Brug altid |escape:'javascript' på alle tekstværdier i Smarty.
Hvor lang tid går der, før jeg ser stjerner i Google?
Google skal først crawle siden igen, før dit nye markup tages i brug. Det kan tage fra få dage til et par uger. I Search Console kan du anmode om hurtig genindeksering af enkeltsider.
Påvirker det mine placeringer i Google?
Strukturerede data er ikke en direkte rangeringsfaktor, men rich snippets med fx pris og stjerner gør dit søgeresultat mere synligt og kan øge klikraten. På sigt er det med til at forbedre din samlede SEO.
Hvordan håndterer jeg moms i pris-feltet?
Brug getRealPrice() som returnerer prisen inkl. moms. Det er den pris, kunden møder i butikken, og den, Google forventer i Product-markup på en B2C-shop. Skal du vise pris ekskl. moms (B2B), brug getPriceExVat() i stedet.
Skal jeg have anmeldelser før jeg viser AggregateRating?
Ja. Tilføj kun AggregateRating, hvis produktet faktisk har anmeldelser. Eksemplet ovenfor tjekker getReviewCount() > 0, så markup ikke tilføjes til produkter uden anmeldelser. Falske eller tomme ratings kan udløse en straf fra Google.
Hvor finder jeg mine firmaoplysninger til Store-markup?
Gå ind i admin under Indstillinger, Firmaoplysninger. De data du udfylder her bliver tilgængelige via $webshop->getCompany() i dit tema, så Store-blokken bliver udfyldt automatisk.
Hvor skal JSON-LD placeres på siden?
Du kan placere det enten i <head> eller i <body>. Begge dele er gyldige ifølge Google. Til produktsider er det almindeligt at placere det i bunden af produkt-templaten.
Min webshop sælger på flere sprog. Skal jeg have markup pr. sprog?
Ja, navne og beskrivelser i markup'et skal afspejle den side, kunden ser. Da $product->getName() og $product->getDescription() automatisk returnerer den oversatte tekst for det aktive sprog, sker det helt automatisk når du bruger eksemplerne her.
Har du brug for hjælp med strukturerede data? Kontakt os på support@shoporama.dk.
Relaterede artikler
SEO i Shoporama
Komplet guide til SEO-funktionerne i Shoporama – fra meta-tags og sitemap til Google Shopping og AI-assistent.
Produktanmeldelser
Lær hvordan du bruger produktanmeldelser i Shoporama. Indsaml kundeanmeldelser automatisk, moderer dem og vis stjernebedømmelser på dine produktsider.
Variabler i et Shoporama-tema
Oversigt over globale og side-specifikke Smarty-variabler tilgængelige i Shoporama-temaer.
Implementer tracking i et Shoporama-tema
Udvikler-guide til at implementere e-commerce tracking i et Shoporama-tema med standard data layer, Google Tag Manager og custom events.
Blog tilknyttet din shop
Komplet guide til blogfunktionen i Shoporama – opret indlæg, planlæg publicering, tilknyt produkter, optimér til søgemaskiner og brug dynamiske...
Prishistorik og Omnibus-direktivet
Shoporama logger automatisk prisændringer og beregner den korrekte førpris iht. Omnibus-direktivet (EU 2019/2161). Standardtemaerne understøtter...
Sæt noindex på en side, produkt eller kategori
Guide til at sætte noindex i Shoporama, så søgemaskiner ikke indexerer bestemte sider.
Relaterede features
Struktureret Data – automatisk Schema.org markup
Automatisk Schema.org markup for produkter, anmeldelser, breadcrumbs og virksomhedsinfo. Rich snippets i Google med stjerner og priser. Inkluderet.
SEO i Shoporama – bliv synlig i Google
Shoporama har indbyggede SEO-funktioner: hurtig hastighed, fuld kontrol over titles og meta descriptions, dynamiske tags, automatiske...