Webmention ist eine W3C-Empfehlung, die zuletzt am 12. Januar 2017 veröffentlicht wurde. Und was genau ist ein Webmention? Es wird beschrieben als…
[…] eine einfache Möglichkeit, jede URL zu benachrichtigen, wenn Sie sie auf Ihrer Website erwähnen. Aus Sicht des Empfängers ist es eine Möglichkeit, Benachrichtigungen anzufordern, wenn andere Websites sie erwähnen.
Kurz gesagt, es ist eine Möglichkeit, einer Website mitzuteilen, dass sie irgendwo, von jemandem, auf irgendeine Weise erwähnt wurde. Die Webmention-Spezifikation beschreibt es auch als eine Möglichkeit für eine Website, andere darüber zu informieren, dass sie diese zitiert hat. Das bedeutet im Grunde, dass Ihre Website ein aktiver Social-Media-Kanal ist, der die Kommunikation von anderen Kanälen (z. B. Twitter, Instagram, Mastodon, Facebook usw.) leitet.
Wie implementiert eine Website Webmentions? In einigen Fällen, wie bei WordPress, ist es so trivial wie die Installation von ein paar Plugins. Andere Fälle sind vielleicht nicht ganz so einfach, aber immer noch ziemlich unkompliziert. Tatsächlich machen wir das jetzt!
Hier ist unser Plan
- Deklarieren Sie einen Endpunkt zum Empfangen von Webmentions
- Verarbeiten Sie Social-Media-Interaktionen zu Webmentions
- Bringen Sie diese Erwähnungen in eine Website/App
- Richten Sie die ausgehenden Webmentions ein
Glücklicherweise gibt es Dienste, die die Dinge extrem einfach machen. Nun, außer dem dritten Punkt, aber hey, es ist nicht so schlimm und ich werde Ihnen zeigen, wie ich es auf meiner eigenen atila.io-Website gemacht habe.
Meine Website ist ein serverseitiger Blog, der vorgerendert und mit NextJS geschrieben ist. Ich habe mich entschieden, Webmention-Anfragen clientseitig zu stellen. Daher funktioniert es problemlos in jeder anderen React-App und mit sehr wenig Refactoring in jeder anderen JavaScript-Anwendung.
Schritt 1: Deklarieren Sie einen Endpunkt zum Empfangen von Webmentions
Um einen Endpunkt zu haben, an dem wir Webmentions empfangen können, müssen wir entweder das Skript schreiben und zu unserem eigenen Server hinzufügen oder einen Dienst wie Webmention.io nutzen (was ich getan habe).
Webmention.io ist kostenlos und Sie müssen nur den Besitz der Domain bestätigen, die Sie registrieren. Die Verifizierung kann auf verschiedene Arten erfolgen. Ich habe dies getan, indem ich ein `rel="me"`-Attribut zu einem Link auf meiner Website zu meinen Social-Media-Profilen hinzugefügt habe. Es reicht ein solcher Link, aber ich habe es für all meine Konten gemacht.
<a
href="https://twitter.com/atilafassina"
target="_blank"
rel="me noopener noreferrer"
>
@AtilaFassina
</a>
Bei dieser Art der Verifizierung müssen wir auch sicherstellen, dass in diesem Twitter-Profil ein Link zurück zu unserer Website zeigt. Sobald wir das getan haben, können wir zu Webmention.io zurückkehren und die URL hinzufügen.
Dadurch erhalten wir einen Endpunkt zum Akzeptieren von Webmentions! Alles, was wir jetzt noch tun müssen, ist, ihn als ``-Tags im `
` unserer Webseiten zu verdrahten, um diese Erwähnungen zu sammeln.<head>
<link rel="webmention" href="https://webmention.io/{user}/webmention" />
<link rel="pingback" href="https://webmention.io/{user}/xmlrpc" />
<!-- ... -->
</head>
Denken Sie daran, `{user}` durch Ihren Webmention.io-Benutzernamen zu ersetzen.
Schritt 2: Verarbeiten Sie Social-Media-Interaktionen zu Webmentions
Wir sind bereit, die Webmentions fließen zu lassen! Aber warten Sie, wir haben ein kleines Problem: Niemand benutzt sie wirklich. Ich meine, ich tue es, Sie tun es, Max Böck tut es, Swyx tut es, und... das ist es im Grunde. Also müssen wir jetzt all diese saftigen Social-Media-Interaktionen in Webmentions umwandeln.
Und raten Sie mal? Dafür gibt es einen fantastischen kostenlosen Dienst. Aber seien Sie gewarnt: Sie sollten anfangen, IndieWeb zu lieben, denn wir werden uns jetzt darin vertiefen.
Bridgy verbindet all unsere syndizierten Inhalte und wandelt sie in richtige Webmentions um, damit wir sie konsumieren können. Mit SSO können wir jedes unserer Profile nacheinander einrichten.
Schritt 3: Holen Sie diese Erwähnungen in eine Website/App
Jetzt sind wir an der Reihe, ein wenig Schwerstarbeit zu leisten. Sicher, Drittanbieterdienste können all unsere Daten verarbeiten, aber es liegt immer noch an uns, sie zu nutzen und anzuzeigen.
Wir werden das in mehrere Stufen aufteilen. Zuerst holen wir die Anzahl der Webmentions. Von dort holen wir die Erwähnungen selbst. Dann verbinden wir diese Daten mit NextJS (aber das müssen Sie nicht tun) und zeigen sie an.
Holen Sie sich die Anzahl der Erwähnungen
type TMentionsCountResponse = {
count: number
type: {
like: number
mention: number
reply: number
repost: number
}
}
Das ist ein Beispiel für ein Objekt, das wir vom Webmention.io-Endpunkt erhalten. Ich habe die Antwort etwas formatiert, um sie besser an unsere Bedürfnisse anzupassen. Wie ich das gemacht habe, erkläre ich gleich, aber hier ist das Objekt, das wir erhalten werden
type TMentionsCount = {
mentions: number
likes: number
total: number
}
Der Endpunkt befindet sich unter
https://webmention.io/api/count.json?target=${post_url}
Die Anfrage schlägt ohne sie nicht fehl, aber die Daten kommen auch nicht. Sowohl Max Böck als auch Swyx kombinieren Likes mit Reposts und Erwähnungen mit Antworten. Bei Twitter sind sie analog.
const getMentionsCount = async (postURL: string): TMentionsCount => {
const resp = await fetch(
`https://webmention.io/api/count.json?target=${postURL}/`
)
const { type, count } = await resp.json()
return {
likes: type.like + type.repost,
mentions: type.mention + type.reply,
total: count,
}
}
Holen Sie sich die tatsächlichen Erwähnungen
Bevor wir zur Antwort kommen, beachten Sie bitte, dass die Antwort paginiert ist, wobei der Endpunkt drei Parameter in der Abfrage akzeptiert
page: die angeforderte Seiteper-page: die Anzahl der auf der Seite anzuzeigenden Erwähnungentarget: die URL, von der Webmentions abgerufen werden
Sobald wir `https://webmention.io/api/mentions` aufrufen und diese Parameter übergeben, ist die erfolgreiche Antwort ein Objekt mit einem einzigen Schlüssel `links`, der ein Array von Erwähnungen des folgenden Typs ist
type TMention = {
source: string
verified: boolean
verified_date: string // date string
id: number
private: boolean
data: {
author: {
name: string
url: string
photo: string // url, hosted in webmention.io
}
url: string
name: string
content: string // encoded HTML
published: string // date string
published_ts: number // ms
}
activity: {
type: 'link' | 'reply' | 'repost' | 'like'
sentence: string // pure text, shortened
sentence_html: string // encoded html
}
target: string
}
Die obigen Daten sind mehr als genug, um eine Kommentar-ähnliche Listenansicht auf unserer Website anzuzeigen. Hier sieht die Fetch-Anfrage in TypeScript aus
const getMentions = async (
page: string,
postsPerPage: number,
postURL: string
): { links: TWebMention[] } => {
const resp = await fetch(
`https://webmention.io/api/mentions?page=${page}&per-page=${postsPerPage}&target=${postURL}`
)
const list = await resp.json()
return list.links
}
Alles in NextJS einbinden
Wir werden uns jetzt einen Moment lang mit NextJS beschäftigen. Es ist in Ordnung, wenn Sie kein NextJS verwenden oder gar keine Webanwendung haben. Wir haben bereits alle Daten, sodass diejenigen unter Ihnen, die nicht mit NextJS arbeiten, einfach zu Schritt 4 übergehen können. Die Übrigen treffen wir dort.
Ab Version 9.3.0 bietet NextJS drei verschiedene Methoden zum Abrufen von Daten
getStaticProps: ruft Daten zur Build-Zeit abgetStaticPaths: gibt dynamische Routen an, die basierend auf den abgerufenen Daten vorgerendert werden sollengetServerSideProps: ruft Daten bei jeder Anfrage ab
Nun ist der Zeitpunkt gekommen, an dem wir entscheiden, wann wir die erste Anfrage zum Abrufen von Erwähnungen stellen. Wir können die Daten auf dem Server mit dem ersten Stapel von Erwähnungen vorrendern oder die gesamte Sache clientseitig erledigen. Ich habe mich für clientseitig entschieden.
Wenn Sie sich ebenfalls für die clientseitige Variante entscheiden, empfehle ich die Verwendung von SWR. Dies ist ein benutzerdefinierter Hook, der vom Vercel-Team entwickelt wurde und gute Caching-, Fehler- und Ladestatus bietet – er unterstützt sogar `React.Suspense`.
Anzeige der Anzahl der Webmentions
Viele Blogs zeigen die Anzahl der Kommentare zu einem Beitrag an zwei Stellen an: oben in einem Blogbeitrag (wie diesem) und unten, direkt über einer Liste von Kommentaren. Folgen wir diesem Muster auch für Webmentions.
Erstellen wir zunächst eine Komponente für die Zählung
const MentionsCounter = ({ postUrl }) => {
const { t } = useTranslation()
// Setting a default value for `data` because I don't want a loading state
// otherwise you could set: if(!data) return <div>loading...</div>
const { data = {}, error } = useSWR(postUrl, getMentionsCount)
if (error) {
return <ErrorMessage>{t('common:errorWebmentions')}</ErrorMessage>
}
// The default values cover the loading state
const { likes = '-', mentions = '-' } = data
return (
<MentionCounter>
<li>
<Heart title="Likes" />
<CounterData>{Number.isNaN(likes) ? 0 : likes}</CounterData>
</li>
<li>
<Comment title="Mentions" />{' '}
<CounterData>{Number.isNaN(mentions) ? 0 : mentions}</CounterData>
</li>
</MentionCounter>
)
}
Dank SWR wird trotz der doppelten Verwendung der `WebmentionsCounter`-Komponente nur eine Anfrage gestellt und beide profitieren vom selben Cache.
Schauen Sie sich gerne meinen Quellcode an, um zu sehen, was passiert
WebmentionsCounter(die Komponente)getMentionsCount(die Hilfsfunktion)Post Layout Component(wo wir die Komponente verwenden)
Anzeige der Erwähnungen
Nachdem wir die Komponente platziert haben, ist es an der Zeit, all diesen sozialen Saft fließen zu lassen!
Zum Zeitpunkt der Verfassung ist `useSWRpages` nicht dokumentiert. Hinzu kommt, dass der Endpunkt von webmention.io keine Sammlungsinformationen in einer Antwort liefert (d. h. kein Offset oder die Gesamtzahl der Seiten). Ich konnte hier keine Möglichkeit finden, SWR zu verwenden.
Meine aktuelle Implementierung verwendet daher einen Zustand, um die aktuelle Seite zu speichern, einen weiteren Zustand, um das Erwähnungs-Array zu verwalten, und `useEffect`, um die Anfrage zu bearbeiten. Die Schaltfläche "Mehr laden" wird deaktiviert, sobald die letzte Anfrage ein leeres Array zurückgibt.
const Webmentions = ({ postUrl }) => {
const { t } = useTranslation()
const [page, setPage] = useState(0)
const [mentions, addMentions] = useState([])
useEffect(() => {
const fetchMentions = async () => {
const olderMentions = await getMentions(page, 50, postUrl)
addMentions((mentions) => [...mentions, ...olderMentions])
}
fetchMentions()
}, [page])
return (
<>
{mentions.map((mention, index) => (
<Mention key={mention.data.author.name + index}>
<AuthorAvatar src={mention.data.author.photo} lazy />
<MentionContent>
<MentionText
data={mention.data}
activity={mention.activity.type}
/>
</MentionContent>
</Mention>
))}
</MentionList>
{mentions.length > 0 && (
<MoreButton
type="button"
onClick={() => {
setPage(page + 1)
}}
>
{t('common:more')}
</MoreButton>
)}
</>
)
}
Der Code ist vereinfacht, um den Fokus auf das Thema dieses Artikels zu legen. Schauen Sie sich ruhig die vollständige Implementierung an
Schritt 4: Handhabung ausgehender Erwähnungen
Dank Remy Sharp ist die Handhabung ausgehender Erwähnungen von einer Website zu anderen recht einfach und bietet für jeden Anwendungsfall oder jede Präferenz eine Option.
Der schnellste und einfachste Weg ist, zu Webmention.app zu gehen, einen API-Token zu erhalten und einen Webhook einzurichten. Wenn Sie einen RSS-Feed haben, ist dasselbe genauso einfach mit einem IFTT-Applet oder sogar einem Deploy-Hook.
Wenn Sie es vorziehen, für diese Funktion keinen weiteren Drittanbieterdienst zu nutzen (was ich vollkommen verstehe), hat Remy ein Open-Source-CLI-Paket namens wm veröffentlicht, das als Postbuild-Skript ausgeführt werden kann.
Aber das reicht noch nicht, um ausgehende Erwähnungen zu verarbeiten. Damit unsere Erwähnungen mehr als nur die Ursprungs-URL enthalten, müssen wir unserer Information Microformats hinzufügen. Microformats sind entscheidend, da sie eine standardisierte Methode für Websites sind, Inhalte so zu verteilen, dass Webmention-fähige Websites sie konsumieren können.
Im Grunde sind Microformats eine Art klassenbasierte Notationen in Markup, die jedem Stück zusätzliche semantische Bedeutung verleihen. Im Fall eines Blogbeitrags werden wir zwei Arten von Microformats verwenden
h-entry: der Beitrags-Eintragh-card: der Autor des Beitrags
Die meisten benötigten Informationen für `h-entry` befinden sich normalerweise im Header der Seite, sodass der Header-Komponente wie folgt aussehen könnte
<header class="h-entry">
<!-- the post date and time -->
<time datetime="2020-04-22T00:00:00.000Z" class="dt-published">
2020-04-22
</time>
<!-- the post title -->
<h1 class="p-name">
Webmentions with NextJS
</h1>
</header>
Und das ist es. Wenn Sie in JSX schreiben, denken Sie daran, `class` durch `className` zu ersetzen, dass `datetime` camelCase ist (`dateTime`) und dass Sie die neue Funktion `Date('2020-04-22').toISOString()` verwenden können.
Für `h-card` ist es ziemlich ähnlich. In den meisten Fällen (wie bei mir) befinden sich die Autoreninformationen unter dem Artikel. So sieht der Footer meiner Seite aus
<footer class="h-card">
<!-- the author name -->
<span class="p-author">Atila Fassina</span>
<!-- the authot image-->
<img
alt="Author’s photograph: Atila Fassina"
class="u-photo"
src="/images/internal-avatar.jpg"
lazy
/>
</footer>
Nun wird bei jeder ausgehenden Erwähnung von diesem Blogbeitrag die vollständige Information dem Empfänger angezeigt.
Zusammenfassung
Ich hoffe, dieser Beitrag hat Ihnen geholfen, mehr über Webmentions (oder sogar über IndieWeb als Ganzes) zu erfahren und hat Ihnen vielleicht sogar geholfen, diese Funktion zu Ihrer eigenen Website oder App hinzuzufügen. Wenn ja, bitte teilen Sie diesen Beitrag in Ihrem Netzwerk. Ich werde Ihnen sehr dankbar sein! 😉
Referenzen
- Web Mentions auf statischen Websites verwenden (Max Böck)
- Client-seitige Webmentions (Swyx)
- Ausgehende Webmentions senden (Remy Sharp)
- Ihre erste Webmention (Aaron Parecki)
Ein gutes Werkzeug zur Überprüfung von Microformats-Markup in Ihren Beiträgen ist https://indiewebify.me/
Und zum Testen Ihrer Webmention-Implementierung schauen Sie sich https://webmention.rocks/ an
Absolut richtig gute Werkzeuge!! Vielen Dank, Kevin!
Ich habe meinen Blog registriert und probiere die Webmention.io-API aus, um zu sehen, welche Erwähnungen ich habe (in der Theorie wird mein Blog bereits ziemlich oft auf Twitter erwähnt), aber die API liefert nur wenige Erwähnungen zurück. Es scheint, dass Brid.ly nur wenige aktuelle Tweets verarbeitet und das nur als Antwort auf Ihre eigenen persönlichen Tweets. Das fand ich etwas enttäuschend. Gibt es eine Möglichkeit, meinen gesamten Tweet-Verlauf als Webmention zu erhalten und Tweets mit Links zu meiner Seite von Dritten zu bekommen?
Leider denke ich, dass es nur so weit zurückverfolgt, wie Sie den Pingback `` auf Ihrer Website haben. Soweit ich weiß, gibt es keine Möglichkeit, die Erwähnungen retroaktiv abzurufen…
Großartiger Artikel, ich habe gerade Webmentions zu meiner Seite hinzugefügt und etwas darüber geschrieben https://gregbenner.life/you-dont-mention-webmentions/, es geht darum, wie man es mit gridsome.js verwendet.