Schema.org Structured Data ist der Kommunikationskanal zwischen Ihrer Website und Suchmaschinen. Richtig implementiert ermöglichen strukturierte Daten Rich Snippets, Knowledge Panels und bessere Darstellungen in den SERPs. Als Entwickler geht es nicht nur darum welche Schemas zu verwenden sind – sondern wie sie technisch korrekt, wartbar und dynamisch integriert werden.
JSON-LD vs. Microdata vs. RDFa
Google empfiehlt JSON-LD als bevorzugtes Format. Der Unterschied:
JSON-LD (JavaScript Object Notation for Linked Data):
- Wird im
<script type="application/ld+json">Tag eingebettet - Vollständig vom HTML-Inhalt getrennt
- Wartbar und übersichtlich
- Dynamisch mit JavaScript generierbar
- Google-Empfehlung
Microdata:
- HTML-Attribute direkt im Content (
itemscope,itemtype,itemprop) - Content und Markup vermischt – schwerer wartbar
- Veraltet, aber noch unterstützt
RDFa:
- Ähnlich wie Microdata, komplexere Syntax
- Nur für spezifische Anwendungsfälle relevant
<!-- JSON-LD (empfohlen): -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Mein Unternehmen"
}
</script>
<!-- Microdata (veraltet): -->
<div itemscope itemtype="https://schema.org/Organization">
<span itemprop="name">Mein Unternehmen</span>
</div>
JSON-LD ist in 95 % der Fälle die richtige Wahl. Die Ausnahme: wenn strukturierte Daten direkt im sichtbaren Content stecken müssen (z. B. für Barrierefreiheitsanforderungen), kann Microdata sinnvoll sein. Für alle anderen Fälle: JSON-LD.
Dynamisches Schema.org mit JavaScript-Frameworks
React / Next.js
// next/head für JSON-LD in Next.js:
import Head from 'next/head';
function ProductPage({ product }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
description: product.description,
offers: {
'@type': 'Offer',
price: product.price,
priceCurrency: 'EUR',
availability: product.inStock
? 'https://schema.org/InStock'
: 'https://schema.org/OutOfStock',
},
};
return (
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
</Head>
);
}
Astro
---
// Typsicher und server-seitig gerendert:
const schema = {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: post.data.title,
datePublished: post.data.date.toISOString(),
author: {
"@type": "Organization",
name: "SEOFX",
},
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
Vanilla JavaScript (Client-side – nur als Fallback)
// Nur wenn serverseitiges Rendering nicht möglich:
const schema = {
'@context': 'https://schema.org',
'@type': 'LocalBusiness',
name: document.querySelector('h1').textContent,
};
const script = document.createElement('script');
script.type = 'application/ld+json';
script.text = JSON.stringify(schema);
document.head.appendChild(script);
Hinweis: Client-seitig injiziertes JSON-LD kann von Googlebot gecrawlt werden (Googlebot rendert JavaScript), aber es ist weniger zuverlässig als serverseitig gerenderte Schemas.
Verwenden Sie TypeScript-Interfaces für Schema-Objekte in größeren Projekten. So vermeiden Sie Tippfehler bei Property-Namen und erhalten IDE-Autovervollständigung. Das npm-Paket „schema-dts" bietet vollständige TypeScript-Typdefinitionen für alle Schema.org-Typen.
Mehrere Schemas auf einer Seite
Eine Seite kann mehrere JSON-LD-Blöcke haben oder ein Array verwenden:
<!-- Mehrere separate Blöcke (beide valide): -->
<script type="application/ld+json">
{"@context": "https://schema.org", "@type": "Organization", ...}
</script>
<script type="application/ld+json">
{"@context": "https://schema.org", "@type": "BreadcrumbList", ...}
</script>
<!-- Oder als @graph-Array in einem Block: -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{"@type": "Organization", ...},
{"@type": "BreadcrumbList", ...},
{"@type": "WebPage", ...}
]
}
</script>
Der @graph-Ansatz ermöglicht Referenzen zwischen Schemas via @id:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "WebPage",
"@id": "https://beispiel.de/produkt/#webpage",
"author": {"@id": "https://beispiel.de/#organization"}
},
{
"@type": "Organization",
"@id": "https://beispiel.de/#organization",
"name": "Mein Unternehmen"
}
]
}
Validierung und Testing
Google Rich Results Test:
- URL eingeben oder Code direkt einfügen
- Zeigt welche Rich Results möglich wären
- Fehler und Warnungen mit konkreten Erklärungen
Schema.org Validator:
- Vollständigere Validierung aller Schema.org-Typen
- Nicht auf Rich-Results-Typen beschränkt
# Automatisierte Validierung in CI/CD-Pipeline:
# Mit dem structured-data-testing-tool (npm):
npx structured-data-testing-tool https://beispiel.de/seite/
# Oder mit dem Google API (requires API key):
curl "https://searchconsearch.googleapis.com/v1/richresults/test" \
-d '{"url": "https://beispiel.de/seite/"}' \
-H "Content-Type: application/json"
Automatisierte Schema-Validierung in der CI/CD-Pipeline findet Fehler bevor sie live gehen. 30 % aller Structured Data Fehler entstehen durch Deployments die bestehende Schemas überschreiben – ein automatischer Test nach jedem Deployment verhindert das.
Häufige Implementierungsfehler
Fehlende required Properties: Jeder Schema.org-Typ hat von Google definierte Pflichtfelder für Rich Results. FAQ ohne name und acceptedAnswer → kein Rich Result.
Falsche URL-Formate: url-Properties müssen absolute URLs sein (https://...), keine relativen Pfade.
Nicht-indexierbare Seiten mit Rich Results: Schema auf Seiten die in robots.txt geblockt oder mit noindex versehen sind, bringt keine Rich Results.
Inhaltliche Inkonsistenz: Schema-Daten müssen mit dem sichtbaren Seiteninhalt übereinstimmen. Ein Preis im Schema der nicht auf der Seite steht → manuelle Abstrafung möglich.
// Sicherheitsfunktion: Escaping für Schema-Ausgabe
function toSafeJson(data) {
return JSON.stringify(data)
.replace(/</g, '\\u003c') // Verhindert script-Injection
.replace(/>/g, '\\u003e')
.replace(/&/g, '\\u0026');
}
Mehr zu Schema.org finden Sie in unserem Artikel über Schema.org LocalBusiness: Alle wichtigen Felder erklärt.