Kanonische URLs, Crawling-Anweisungen und Sitemaps einrichten
Die URLs für Suchsysteme auf Seiten, in Links und in der Sitemap aufeinander abstimmen. Crawling-Anweisungen für öffentliche Pfade festlegen und alte URLs mit den neuen Dokumenten verbinden.
Doppelte URLs und Sprachversionen ordnen
Auch eine neu veröffentlichte Betriebsinformation braucht Links zu ihrer URL, damit Crawler sie entdecken können. Ist die URL bekannt, können robots-Regeln oder der Server dennoch den Abruf des Inhalts verhindern. Liegt derselbe Artikel unter mehreren URLs, muss eine kanonische URL gewählt werden. Interne Links und Sitemaps, Crawling-Anweisungen und canonical behandeln jeweils eines dieser Probleme. Wir betrachten die Einstellungen in der Reihenfolge, in der öffentliche Dokumente entdeckt und verarbeitet werden.
Wenn derselbe Artikel unter mehreren URLs erreichbar ist, zuerst die künftig verwendete kanonische URL festlegen. Die Beziehungen zwischen http und https, mit und ohne www, abschließendem Schrägstrich und alten Slugs auflisten. Gleichwertige URLs, die entfallen sollen, über permanente Weiterleitungen des Servers oder Hostings mit der kanonischen URL verbinden. URLs, die sich nur in Tracking-Parametern unterscheiden, können bei gleichem Inhalt denselben canonical verwenden. Liefern Filter tatsächlich andere Inhalte, zunächst prüfen, ob überhaupt eine Dublette vorliegt.
Die zweite Seite einer Seitennavigation enthält andere Inhalte als die erste. Daher nicht pauschal für alle Seiten die erste Seite als kanonisch angeben. Echte a href-Links zur nächsten Seite bereitstellen. Bei mehrsprachigen Seiten für jede Sprache eine selbstreferenzierende kanonische URL und gegenseitige hreflang-Verweise anlegen. Keine URLs für nicht vorhandene Übersetzungen ausgeben.
Sitemap, interne Links, canonical und Weiterleitungen müssen dieselbe kanonische URL angeben. Die Einrichtung anhand von Googles Anleitung zu kanonischen URLs vornehmen. Nach der Bereitstellung mit der URL-Prüfung kontrollieren, welche kanonische URL das Suchsystem tatsächlich gewählt hat.
Alte und neue URLs Zeile für Zeile zuordnen
Vor dem Umbau die vorhandenen URLs als Liste speichern und jeder eine Behandlung zuweisen: beibehalten, verschieben, als historische Aufzeichnung erhalten oder beenden. Verschiebungen desselben Inhalts per 301/308 mit der neuen URL verbinden. Aktuelle Informationen und historische Aufzeichnungen nach Geltungszeitraum und Dokumentzweck unterscheiden. Historische Aufzeichnungen können mit ihrem damaligen Stand und einem Link zu den aktuellen Informationen unter einer eigenen URL erhalten bleiben.
Wird beispielsweise /notice/old-guide nach /guides/apply verschoben, Weiterleitung, Menü- und Inhaltslinks, canonical und Sitemap gemeinsam ändern. Bleibt die alte Anleitung unter /archive/2024/apply erhalten, ihren Inhalt nicht mit aktuellen Hinweisen überschreiben. Ob das Archiv aus der Suche ausgeschlossen wird, entscheidet die Veröffentlichungsrichtlinie. Nicht pauschal noindex setzen, nur weil ein Dokument alt ist.
In der Routenzuordnung alte URL, neue URL, erwarteten Statuscode, kanonische URL, Sitemap-Aufnahme und eingehende Links erfassen. Prüfen, ob alte URLs über weitere alte URLs mehrfach weiterleiten oder Schleifen entstehen. Bei einem Domainwechsel auch die Umgebungswerte für absolute URLs, die URLs der Vorschaubilder sowie die Properties und Eigentumsbestätigungen der Suchwerkzeuge aktualisieren. Siehe Googles Anleitung zum Umzug mit URL-Änderungen.
Alte URLs können in Suchergebnissen, externen Artikeln und gespeicherten Links fortbestehen. Eine permanente Weiterleitung bei der Verschiebung desselben Artikels führt Besucher und Crawler zum neuen Dokument. Historische Aufzeichnungen früherer Betriebsregeln beantworten dagegen Fragen zu jener Zeit und behalten deshalb ihre eigene URL und ihren Zeitraum. Alle alten URLs zur Startseite zu schicken, erschwert die Verbindung zu dem, was Besucher gesucht haben.
robots.txt und Antwortheader ändern
Bei Next.js prüfen, ob app/robots.ts oder public/robots.txt tatsächlich ausgeliefert wird. Bei anderen Servern die robots.txt im Web-Stammverzeichnis und die Sperrregeln von CDN und Proxy prüfen. Enthält Disallow öffentliche Pfade, seinen Umfang entsprechend der Veröffentlichungsrichtlinie einschränken. Auch verbliebene noindex-Anweisungen in HTML-meta robots und HTTP-X-Robots-Tag untersuchen. Ein noindex in robots.txt wird von Google nicht als Anweisung zum Ausschluss aus dem Index unterstützt.
Über Suchbots und Trainingsbots getrennt nach Zweck entscheiden. Das folgende Beispiel gehört zu einer Website, die Such-Crawling zulässt und OpenAI-Trainings-Crawling einschränkt. Websites, die auch Trainings-Crawling zulassen, passen die Disallow-Regel für GPTBot an ihre Richtlinie an.
User-agent: *
Allow: /
Disallow: /admin$
Disallow: /admin?
Disallow: /admin/
Disallow: /preview$
Disallow: /preview?
Disallow: /preview/
User-agent: OAI-SearchBot
Allow: /
Disallow: /admin$
Disallow: /admin?
Disallow: /admin/
Disallow: /preview$
Disallow: /preview?
Disallow: /preview/
User-agent: GPTBot
Disallow: /
Sitemap: https://example.com/sitemap.xml
In einer Gruppe für einen bestimmten Bot auch dessen ausgeschlossene Pfade ausdrücklich angeben. Im Beispiel werden die Pfade in den Suchbot-Gruppen wiederholt, damit Ausschlüsse auch bei einer Verarbeitung ohne Zusammenführung mit der allgemeinen Gruppe gelten. Vorschaupfade durch echte Authentifizierung schützen. Prüfen, ob breit gefasste Sperrregeln CSS, JavaScript, Bilder oder öffentliche APIs erfassen, die für den öffentlichen Inhalt benötigt werden. Liefert die WAF Bots eine Anmeldung, eine Challenge oder 403, reicht eine robots-Freigabe nicht aus.
Googles noindex-Anweisung steht in der Seitenantwort. Der Crawler muss diese Antwort erhalten können, um sie zu lesen. OAI-SearchBot sammelt Material für die Suche, GPTBot für das Modelltraining. Deshalb die erlaubten Pfade je Zweck festlegen. Google noindex · OpenAI-Bots
/admin/ allein erfasst weder /admin noch /admin?mode=edit. Die obigen Regeln kennzeichnen mit $ das genaue Pfadende, mit ? die Abfrage am Stamm dieses Pfads und mit / die Unterpfade. /administrator fällt unter keine dieser drei Regeln. Das Beispiel beruht auf den von Google unterstützten Zeichen * und $ sowie dessen Regeln für Pfadvergleiche. Bei anderen Crawlern den unterstützten Umfang des jeweiligen Anbieters prüfen. robots-Pfadregeln
Die Sitemap aus öffentlichen Daten erzeugen
Eine Sitemap aus den Ergebnissen öffentlicher Abfragen zu erzeugen, reduziert Auslassungen gegenüber einer separaten handgepflegten Liste. In Next.js liefert app/sitemap.ts URLs und Änderungsdaten zurück; andere Stacks erzeugen aus denselben Daten XML. listPublicGuides unten fragt die vollständige Liste unter Anwendung der Veröffentlichungsbedingungen ab. Liefert die Datenbank nur einzelne Seiten, muss bis zur letzten Seite weitergeblättert werden.
Der folgende Block zeigt den Funktionsausschnitt für das Umwandlungsprinzip. Die vollständige ausführbare app/sitemap.ts samt Imports folgt im nächsten Abschnitt.
export default async function sitemap() {
const guides = await listPublicGuides()
return guides.map(g => ({
url: g.info.canonical,
...(g.info.dateModified ? { lastModified: g.info.dateModified } : {})
}))
}
guides ist das Array aller öffentlichen Artikel. map erzeugt für jeden Artikel einen Sitemap-Eintrag. url erhält den geprüften Wert info.canonical; lastModified wird nur ergänzt, wenn dateModified vorhanden ist. ... fügt bedingt erzeugte Eigenschaften in das Objekt ein. Die Datumszeichenfolge unverändert verwenden, damit einem nur als Datum bekannten Änderungsstand keine willkürliche Mitternacht angehängt wird.
lastModified enthält das Datum einer tatsächlichen Änderung am Inhalt oder an wichtigen Links. Nicht mit dem Bereitstellungszeitpunkt oder der aktuellen Zeit jedes Requests füllen. Ohne verlässliches Änderungsdatum weglassen. Sitemap-URLs müssen öffentliche kanonische URLs mit erfolgreicher Antwort sein. Zurückgezogene, fehlerhafte und weiterleitende URLs ausschließen. Die erzeugte Datei gemäß den Richtlinien zur Sitemap-Erstellung bereitstellen und anschließend in den Suchwerkzeugen den Einreichungs- und Verarbeitungsstatus prüfen.
RSS und Atom sind Dokumentformate für das Abonnieren neuer Artikel oder die Anbindung externer Dienste. Ein Feed ist eine URL, die Titel, Links und Datumsangaben in einem solchen Format zusammenführt. Bei seinem Betrieb dieselben Veröffentlichungsbedingungen wie für die Sitemap anwenden und Titel, kanonischen Link, Datum und eine stabile Eintrags-ID ausgeben. Eine URL für Feedreader oder angebundene Dienste festlegen und den Feed bei Veröffentlichung, Änderung und Rücknahme aktualisieren.
Eine Sitemap aus öffentlichen Abfragen lässt die auffindbaren URLs gemeinsam mit den Artikeln im CMS wachsen. Gibt es beispielsweise 120 Detailartikel, aber nur die ersten 20 Listeneinträge in der Sitemap, hängt die Entdeckung der übrigen 100 von anderen Linkwegen ab. Die Verbindung aus vollständiger Abfrage und Prüfung funktionierender URLs deckt diese Lücke auf. lastmod weist auf geänderte Dokumente hin und muss daher dem tatsächlichen Zeitpunkt wesentlicher Änderungen entsprechen.
robots und Sitemap des Beispiels vervollständigen
app/robots.ts weist auf das Crawling öffentlicher Pfade hin und schließt Verwaltungs- und Vorschaupfade aus. Authentifizierung wird separat in der entsprechenden Serverfunktion umgesetzt. app/sitemap.ts enthält die Ergebnisse der öffentlichen Abfrage und tatsächlich vorhandene Archivseiten.
import type { MetadataRoute } from 'next'
import { SITE_ORIGIN } from '../lib/site'
export default function robots(): MetadataRoute.Robots {
return { rules: [{ userAgent: '*', allow: '/', disallow: ['/admin$', '/admin?', '/admin/', '/preview$', '/preview?', '/preview/'] }],
sitemap: new URL('/sitemap.xml', SITE_ORIGIN).href }
}
import type { MetadataRoute } from 'next'
import { listPublicGuides } from '../lib/guides'
import { SITE_ORIGIN } from '../lib/site'
export const dynamic = 'force-dynamic'
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const guides = await listPublicGuides()
return [
{ url: SITE_ORIGIN },
{ url: new URL('/policies/opening-hours', SITE_ORIGIN).href },
{ url: new URL('/archive/opening-2025', SITE_ORIGIN).href },
...guides.map(g => ({ url: g.info.canonical,
...(g.info.dateModified ? { lastModified: g.info.dateModified } : {}) })),
]
}
Prüfen, dass Entwürfe, nicht vorhandene und weiterleitende URLs in der Sitemap fehlen und jede URL ein funktionierendes öffentliches Dokument zurückgibt. Bei steigender URL-Zahl Dateien aufteilen und über einen Sitemap-Index verbinden. Für eine gewöhnliche Sitemap-Datei gelten bei Google die Grenzen von 50.000 URLs und 50MB unkomprimiert. Anhand der Richtlinien zur Sitemap-Erstellung die Dateigröße und die Vollständigkeit der Gesamtliste prüfen.
Der erste Code gehört zu app/robots.ts, der zweite zu app/sitemap.ts. Die Funktion robots übergibt rules an Next.js zur Umwandlung in robots.txt; sitemap übergibt das Array öffentlicher URLs zur Umwandlung in XML. Startseite, historische Aufzeichnungen, Belegdokumente und aktuell öffentliche Artikel sind enthalten, Entwürfe nicht. Mit curl http://localhost:3027/robots.txt und curl http://localhost:3027/sitemap.xml die tatsächlich erzeugten Ergebnisse lesen.
Das aktuelle Beispiel verwendet eine allgemeine Crawling-Freigabe. Wer das GPTBot-Sperrbeispiel aus dem vorherigen Abschnitt übernimmt, muss dieselbe Richtlinie auch in rules dieser robots-Funktion abbilden. Nicht gleichzeitig public/robots.txt und app/robots.ts anlegen und dadurch offenlassen, welche Datei antwortet.
Crawlability und Indexierbarkeit getrennt prüfen
Crawlability beschreibt die Bedingungen, unter denen Crawler Material abrufen können. Indexierbarkeit beschreibt, ob das abgerufene Material für den Index infrage kommt. Trotz HTTP 200 und robots-Freigabe können noindex, die Auswahl eines kanonischen Dokuments oder die Inhaltsbewertung eine Aufnahme in die Suche verhindern. Eine Crawling-Sperre kann verhindern, dass der Crawler noindex innerhalb der Seite liest.
Soll eine öffentliche Datei nur aus der Suche ausgeschlossen werden, noindex über meta robots oder X-Robots-Tag in einer abrufbaren Antwort bereitstellen. Private Materialien durch Authentifizierung und Berechtigungen schützen. Prüfen, ob Anfragen unberechtigter Nutzer tatsächlich blockiert werden. robots.txt ist eine öffentlich sichtbare Hinweisdatei und kein Mittel zum Verbergen geheimer Pfade.
Das Crawl-Budget betrifft die Ressourcen- und Nachfragegrenzen beim Crawling einer Website durch Suchmaschinen. Bei sehr großen Websites und schnell wechselnden Materialien können Dubletten, endlose URL-Räume und Probleme mit Serverantworten die Crawling-Effizienz beeinflussen. Bei einer kleinen Informationswebsite zuerst Entdeckungslinks, Fehler, Inhalte und Ursachen für den Indexausschluss wichtiger Dokumente prüfen. Crawling-Leitfaden für große Websites
Lokale Betriebe stellen Adresse, Öffnungszeiten und Kontaktdaten je Standort bereit. Produkte benötigen Preis, Verfügbarkeit und Kaufbedingungen; Videos Wiedergabe-URL, Vorschaubild und Länge. Übersetzte Seiten brauchen Inhalte in der jeweiligen Sprache und einander zugeordnete hreflang-URLs. Welche Informationen ergänzt werden, hängt vom Inhaltstyp ab.
Teilnahme an generativer Suche und Nutzung des Inhalts festlegen
Seiten, die an Googles generativer Suche teilnehmen sollen, müssen indexiert sein und Snippets in den Suchergebnissen zulassen. In Search Console unter Settings → Search generative AI auch die wirksamen Werte der betreffenden und der übergeordneten Property prüfen. Include ist der Standardwert; untergeordnete Properties können den Wert ihrer Eltern übernehmen. Erscheint eine Seite in der Suche, nimmt aber nicht an generativen Funktionen teil, nacheinander Indexstatus, Snippet-Anweisungen und diese Einstellung abgleichen. Teilnahmebedingungen · Einstellung Search generative AI
<!-- Option zum Ausschließen von Snippets für die gesamte Seite: nicht die Standardeinstellung der Beispielwebsite -->
<meta name="robots" content="nosnippet">
<!-- Andere Option: maximale Snippet-Länge begrenzen -->
<meta name="robots" content="max-snippet:160">
<!-- Option zum Ausschließen eines Seitenabschnitts aus Snippets -->
<p>Sonntags 10–17 Uhr, am ersten Sonntag geschlossen.</p>
<div data-nosnippet>Zusätzlicher Text zur Bedienung der Seite</div>
Die drei Codebeispiele sind unterschiedliche Optionen. nosnippet verhindert Text-Snippets und begrenzt auch die Nutzung des Inhalts als direkte Eingabe für Google AI Overviews und AI Mode. max-snippet:0 bedeutet denselben Ausschluss; positive Werte beeinflussen die Länge von Snippets und direkten Eingaben. data-nosnippet wird an span, div oder section gesetzt und schließt den betreffenden Teil aus. Stehen darin wesentliche Schließungsbedingungen, kann die Grundlage für die benötigte Antwort fehlen. Für gesonderte Genehmigungen, Verträge oder strukturierte Daten gibt es Ausnahmen. Den Geltungsbereich der Anweisung deshalb in der Dokumentation prüfen. Googles Snippet-Anweisungen
Googlebot übernimmt das Crawling für Google Search. Google-Extended ist ein robots-Produkttoken, das bestimmtes Gemini-Modelltraining und festgelegte Grounding-Nutzungen außerhalb von Google Search steuert. Das Token allein steuert weder Rankings in Google Search noch die Teilnahme an generativer Suche. Der Ausschluss über Search generative AI betrifft bestimmte generative Suchfunktionen und steuert weder andere Suchrankings noch Modelltraining. Aufgabenbereiche der Google-Crawler · Geltungsbereich der Einstellung
Auch OpenAIs OAI-SearchBot und GPTBot haben getrennte Zwecke: Suche und Training. Nach der Freigabe öffentlicher Pfade die robots-Header und Inhalte der tatsächlichen Antworten lesen und die Anfrageergebnisse aus den Serverlogs festhalten. Werden Suchteilnahme und Trainingsfreigabe in einem einzigen Schalter „KI erlauben“ zusammengefasst, lässt sich schwer erklären, welcher Zweck eingeschränkt wurde.
Aktuelle Artikel per RSS anbieten und bei Änderungen und Rücknahmen aktualisieren
RSS ist ein Format, mit dem Feedreader dieselbe URL regelmäßig abrufen und neue Artikel finden. So erreichen Nachrichten Leser, die nicht jedes Mal die Startseite besuchen, und andere Dienste. Die Sitemap meldet Suchwerkzeugen die öffentlichen URLs der Website. Der RSS-Feed dieser Übung liefert Titel, kanonische URL und Zusammenfassung der 20 neuesten Beiträge. Google akzeptiert auch RSS und Atom als Sitemap; ein Feed mit nur aktuellen Artikeln ersetzt jedoch keine vollständige URL-Liste. Leitfaden zu Sitemap-Formaten
Die folgende feed.mjs im selben Ordner wie identity-time.mjs speichern. renderFeed wählt aus allen Quelldatensätzen öffentliche Dokumente aus und nimmt anschließend die 20 neuesten nach Veröffentlichungsdatum. guid erhält die Dokument-ID, link die aktuelle kanonische URL. So bleibt die Identität desselben Artikels auch bei Änderungen an Titel oder Slug erhalten. RSS-2.0-Spezifikation
import { describeDocument, instant } from './identity-time.mjs';
export function escapeXml(value) {
// Nach XML 1.0 unzulässige Zeichen und einzelne Surrogate zurückweisen.
for (const char of String(value)) {
const n = char.codePointAt(0);
if (!(n === 9 || n === 10 || n === 13 || (n >= 32 && n <= 0xD7FF)
|| (n >= 0xE000 && n <= 0xFFFD) || n >= 0x10000)) throw new Error('Invalid XML character');
}
return String(value).replace(/[&<>"']/g,
c => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c]);
}
export function renderFeed(rows, origin, asOf) {
const x = escapeXml;
const publicRows = rows.map(doc => ({ doc, identity: describeDocument(doc, asOf, origin) }))
.filter(row => row.identity)
.sort((a, b) => order(b.doc.publishedAt) - order(a.doc.publishedAt))
.slice(0, 20);
const items = publicRows.map(({ doc, identity }) => {
// RSS-pubDate verlangt eine Uhrzeit. Bei Dokumenten mit reinem Datum dieses optionale Feld weglassen.
const date = identity.datePublished;
const pubDate = date?.includes('T') ? `<pubDate>${new Date(instant(date)).toUTCString()}</pubDate>` : '';
return `<item><title>${x(doc.title)}</title><link>${x(identity.canonical)}</link>
<guid isPermaLink="false">${x(identity.id)}</guid>${pubDate}
<description>${x(x(doc.summary))}</description></item>`;
}).join('');
return `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><title>Nachrichten der fiktiven Bibliothek</title>
<link>${x(origin)}</link><description>Die 20 neuesten öffentlichen Meldungen</description>${items}</channel></rss>`;
}
// Einträge mit reinem Datum nach dem Beginn des koreanischen Kalendertags sortieren; nicht für pubDate verwenden.
function order(value) {
return value === null ? -Infinity : instant(value.length === 10 ? value + 'T00:00:00+09:00' : value);
}
Zeichen wie & und < haben in XML eine syntaktische Funktion. Deshalb maskiert escapeXml den Text. RSS-description kann vom Empfänger als HTML gelesen werden, daher wird die Zusammenfassung zweimal maskiert. Der erste Durchgang bewahrt die Zeichen im HTML, der zweite die Zeichen dieses HTML innerhalb von XML. Unzulässige Steuerzeichen lösen einen Fehler aus. pubDate enthält den Zeitpunkt der Erstveröffentlichung. Ist nur das Datum bekannt, entfällt dieses optionale Feld.
Bei einer Inhaltsänderung Zusammenfassung und Link unter derselben guid aktualisieren. Dieser RSS-Feed enthält keinen separaten Änderungszeitpunkt je Eintrag. Benötigt eine Anbindung diesen Zeitpunkt, ein vom empfangenden Werkzeug unterstütztes Feld wählen, etwa updated in Atom. Zurückgezogene Artikel fehlen im nächsten Feed; bereits vom Feedreader gespeicherte Artikel können erhalten bleiben. Der Zugriff auf den Originaltext muss gesperrt und entschieden werden, ob die Korrektur in einem eigenen Beitrag mitgeteilt wird.
Der Server der Bildübung liefert dieses Ergebnis unter /rss.xml als application/rss+xml aus. Im head der Startseite steht ein Link mit rel="alternate". Zwei Prüfungen getrennt durchführen: die RSS-URL direkt öffnen und das XML lesen; anschließend beobachten, wie ein echter Feedreader neue Artikel, Änderungen unter derselben ID und Rücknahmen verarbeitet.