Webentwicklung: Detaillierte Linkvorschauen von Websites automatisiert erstellen
Seite 2: Das Open Graph Protocol als de-facto-Standard
Neben den standardisierten Metadaten gibt es das Open Graph Protocol (OGP), die "de facto Standard-Erweiterung". Dieses Protokoll ergänzt die Angabe von Vorschaubildern, Videos und Audiodateien, ermöglicht das Festlegen eines Typen (wie Artikel, Musik oder Website) sowie weiterer Metadaten für das HTML-Dokument. Dabei überschneidet sich das OGP mit einigen vereinheitlichten Metadaten. Es unterscheidet zwischen den verpflichtenden Metadaten og:title, og:type, og:image, og:url
und folgenden optionalen Metadaten
og:audio
og:description
og:determiner
og:locale
og:locale:alternate
og:site_name
og:video
Die Deklaration der OGP-Daten weicht minimal von den standardisierten Metadaten ab:
<meta property="og:title" content="Never Gonna Give You Up">
<meta property="og:type" content="music.song">
<meta property="og:image"
content="https://i.scdn.co/image/ab67616d0000b273255e131abc1410833be95673">
<meta property="og:url"
content="https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT">
Listing 3: Angabe der erforderlichen Open-Graph-Metadaten für einen Spotify-Song
Anstelle des name
-Attributs verwendet das OGP in Listing 3 das property
-Attribut. Abhängig vom Typ og:type
können weitere grundlegende OGP-Metadaten nötig sein. Für einen Song wären dies zum Beispiel:
music:duration
music:album
music:album:disc
music:album:track
music:musician
Gesonderte Metadaten folgen Open Graph Protocol
Die Angabe der gesonderten Metadaten für einen Song folgt dem Schema des Open Graph Protocol:
<meta name="music:duration" content="214">
<meta name="music:album"
content="https://open.spotify.com/album/6N9PS4QXF1D0OWPk0Sxtb4">
<meta name="music:album:track" content="1">
<meta name="music:musician"
content="https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt">
Listing 4: Gesonderte OGP-Metadaten zur Deklaration eines Songs
Der einzige Unterschied zum OGP-Standard in Listing 4 besteht darin, dass das Präfix og
durch eine dem Typ entsprechende Alternative (hier music
) ausgetauscht wird. Entwicklerinnen und Entwickler sollten dabei jedoch beachten, dass sich nicht jede Website strikt an die OGP-Vorgaben hält. Beim dargestellten Song von Spotify fehlt etwa die Angabe des Albums (music:album:disc
), da sie aus Sicht von Spotify vermutlich irrelevant ist.
Neben dem Song gibt es weitere Typen:
music.album
music.playlist
music.radio_station
video.movie
video.episode
video.tv_show
video.other
article
book
profile
website
Zudem dokumentiert die offizielle Seite nicht alle OGP-Metadaten. So dokumentiert Meta/Facebook etwa die Eigenschaft article:content_tier
, die auf ogp.me nicht erwähnt wird. Wer die Vorschau testen möchte, kann dazu den LinkedIn Post Inspector heranziehen, der jedoch nicht alle Eigenschaften des Open Graph Protocol betrachtet. Die Twitter Cards ähneln dem OGP stark. Hier existieren jedoch einige zusätzliche Meta-Tags wie das Twitter-Handle. Die Angabe von Metadaten erfolgt mit dem Präfix twitter
. Die Angabe des Twitter-Handles für die Twitter Card eines Spotify-Songs hat dann die folgende Form: <meta name="twitter:site" content="@spotify">
Weitere Angaben wie twitter:title, twitter:description
sind für das Erstellen einer eigenen Linkvorschau redundant, können jedoch als Fallback verwendet werden, falls korrespondierende Metadaten (description oder og:description) nicht gesetzt sind.
Twitter Card steuert Linkvorschau
Die Eigenschaft twitter:card
wird von Twitter verwendet, um die Darstellung der Card (Linkvorschau) zu beeinflussen. Auch Dritte können sie interpretieren. So verwendet Slack die Angaben in Verbindung mit den Metadaten twitter:label1, twitter:data1, twitter:label2
und twitter:data2
für die eigene Linkvorschau. Entwicklerinnen können die Label/Data-Paare für die eigene Vorschau heranziehen. Sie enthalten benutzerdefinierte Angaben, wie etwa den Preis eines Produkts:
<meta name="twitter:label1" content="Preis">
<meta name="twitter:data1" content="€42">
Listing 5: Angabe des Produktpreises durch Twitter-Label
Inhalte erhalten über das Format oEmbed
Das oEmbed-Format weicht vom OGP und den Twitter Cards ab. Statt meta-Elemente auszulesen, spricht dabei ein Konsument ("consumer") die API-Schnittstelle des Anbieters ("provider") an, um Inhalte über die anzufragende Seite zu erhalten. Auch für den Spotify-Song gibt es eine oEmbed-Schnittstelle, die entweder ein Link-Element im Quellcode, die Angabe des Link-Headers oder ein Lookup in der Provider-Liste anfragen kann. Letztere Methode ist nicht empfehlenswert, da sie nur eine begrenzte Anzahl an Providern (aktuell 296) enthält und so nicht sichergestellt ist, dass der oEmbed-Endpunkt gefunden wird.
<link
rel="alternate"
type="application/json+oembed"
href="https://open.spotify.com/oembed?url=https%3A%2F%2Fopen.spotify.com%2Ftrack%2F4cOdK2wGLETKBW3PvgPWqT"
>
Listing 6: Angabe der oEmbed-Schnittstelle für einen Spotify-Song
Die Anfrage des Endpunktes erfolgt durch document
mit folgender Eingabe: document.querySelector('link[rel="alternate"][type="application/json+oembed"]')?.href;
Das JSON-Ergebnis – wie folgendes Listing es zeigt – ermöglicht das Abrufen des Endpunktes:
{
"html": "<iframe>...</iframe>",
"width": 456,
"height": 152,
"version": "1.0",
"provider_name": "Spotify",
"provider_url": "https://spotify.com",
"type": "rich",
"title": "Never Gonna Give You Up",
"thumbnail_url": "https://i.scdn.co/image/ab67616d00001e025755e164993798e0c9ef7d7a",
"thumbnail_width": 300,
"thumbnail_height": 300
}
Listing 7: Resultat der Abfrage der oEmbed-Schnittstelle
Das Resultat aus Listing 7 enthält die optionalen Angaben Anbieter (provider_name), Titel (title), Thumbnail (thumbnail_url) sowie eine dynamische Vorschau (html). Die Vorschau existiert, wenn der Typ auf rich
gesetzt ist, alternativ kann er die Werte photo, video
und link
enthalten. Die Angaben über den Autor (author_name, author_url) sowie die Cache-Dauer (cache_age) sind weiterhin optional. Grundsätzlich können Programmierer die oEmbed-Schnittstellen ohne Autorisierung abrufen. Allerdings verlangt Meta/Facebook zusätzlich einen API-Key, der über den Anfrage-Parameter access_token
gesetzt wird.
Strukturierte Daten für bestimmte Teile der Webseite
Schließlich stehen den Entwicklern auch noch die strukturierten Daten zur Verfügung, bei denen die Implementierung durch Resource Description Framework in Attributes (RDFa), Mikrodaten oder JSON for Linked Data (kurz JSON-LD) erfolgt. Google empfiehlt JSON-LD, weshalb dieses Format hier genutzt wird. Im Gegensatz zu meta
-Elementen oder dem oEmbed-Format beschreiben strukturierte Daten nicht zwangsläufig die komplette Website oder eine Unterseite, sondern können sich auch auf bestimmte Teile beschränken, etwa auf den Autor des Artikels oder das Unternehmen. Für die Angabe strukturierter Daten mittels JSON-LD verwenden Entwickler das script
-Element als Container mit den strukturierten Daten als Inhalt:
<script type="application/ld+json">
{
"@context": "http://schema.org/",
"@type": "MusicRecording",
"@id": "https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
"url": "https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
"name": "Never Gonna Give You Up",
"description": "Listen to Never Gonna Give You Up on Spotify. Rick Astley · Song · 1987.",
"datePublished": "1987-11-12",
"potentialAction": {
"@type": "ListenAction",
"target": [...],
"expectsAcceptanceOf": {
"@type": "Offer",
"category": "free",
"eligibleRegion": []
}
}
}
</script>
Listing 8: script-Element mit JSON-LD Inhalt
Die Eigenschaften des Objekts entstammen dabei der korrespondierenden Schema-Seite, in diesem Fall MusicRecording. Dabei muss ein Programmierer immer sowohl @context
als auch @type
angeben. Neben diesen beiden und weiteren Eigenschaften aus Listing 8 lässt sich dann beispielsweise noch die Attribute duration
oder byArtist
hinzufügen (siehe Abb. 2). Die Eigenschaften übergeordneter Objekte können Entwicklerinnen und Entwickler ebenfalls nutzen. Bei MusicRecording wären dies CreativeWork
und Thing
.
In den geschilderten Fällen beschränken sich JSON-LD-Objekte nicht auf jeweils ein Objekt pro HTML-Dokument, sodass Entwicklerinnen auch weitere Objekte wie Organisation verwenden können. Zum Validieren können sie den Dienst Google Validation für strukturierte Daten verwenden.
Eigene Vorschau generieren
Die bisher in diesem Beitrag vorgestellten Daten wie Autor, Publikationsdatum und Genre sind grundsätzlich interessant für eine Linkvorschau. Nachdem in den vorangegangenen Abschnitten einzelne Methoden zur Datengewinnung erläutert wurden, geht es nun daran, diese zu einer Vorschau zusammenzusetzen. In den Codebeispielen überschneiden sich diverse Eigenschaften wie das Publikationsdatum oder die Beschreibung. Dies ist insbesondere für die Absicherung von Vorteil, da so die Wahrscheinlichkeit sinkt, dass ein Wert für die Vorschau nicht gefüllt ist. Für die Vorschau aus Abbildung 1 benötigen Entwickler Host, Titel, Beschreibung sowie ein Vorschaubild. Folgendes Listing zeigt, wie die Vorschau auf diese Werte zugreift:
function getMeta(name) {
const attribute = name.toLowerCase().startsWith('og:')
? 'property' : 'name';
const element = document.querySelector(`meta[${attribute}="${name}"]`);
if (element) {
return element.getAttribute('content');
}
}
const { hostname } = new URL(url);
const titleTag = document.querySelector('title');
const titleMeta = getMeta('og:title') || getMeta('twitter:title');
const title = titleTag ? titleTag.textContent : titleMeta;
const img = getMeta('og:image') || getMeta('og:image:url')
|| getMeta('og:image:secure_url') || getMeta('twitter:image');
const description = getMeta('description')
|| getMeta('og:description') || getMeta('twitter:description');
Listing 9: Datensammlung für die Linkvorschau mittels Node.js
Strukturierte Daten kommen in Listing 9 nicht zum Einsatz, da sie zur Replikation der Linkvorschau aus Abbildung 1 nicht nötig sind und Twitter lediglich die Beschreibung anzeigt. Grundsätzlich kann die Vorschau auch Autoren, Lesezeit und die Anzahl an Kommentaren ebenfalls anzeigen. Dies ist insbesondere bei Zeitungsartikeln und Blogbeiträgen von Interesse. So nutzt heise.de das Schema NewsArticle auf Artikelseiten, das unter anderem author
und commentCount isAccessibleForFree
enthält. Wer einen Überblick über verwendete JSON-LD-Schemata einer Website erhalten möchte, kann nachfolgenden Befehl in der Browser-Konsole ausführen: $$("script[type='application/ld+json']").map(x => JSON.parse(x.textContent))