Grundlagen von JavaScript-SEO

JavaScript ist ein wichtiger Bestandteil der Webplattform, da es viele Funktionen bietet, die das Web zu einer leistungsstarken Anwendungsplattform machen. Deshalb solltest du deine JavaScript-fähigen Webanwendungen über die Google Suche auffindbar machen. So lassen sich neue Nutzer gewinnen und vorhandene Nutzer erneut ansprechen, wenn sie nach Inhalten suchen, die in deiner Webanwendung verfügbar sind. JavaScript wird in der Google Suche mit einer Evergreen-Version von Chromium ausgeführt, du kannst aber einige Optimierungen vornehmen.

Hier erfährst du, wie JavaScript in der Google Suche verarbeitet wird. Außerdem beschreiben wir Best Practices zur Verbesserung von JavaScript-Webanwendungen für die Google Suche.

Verarbeitung von JavaScript durch den Googlebot

Die Verarbeitung von JavaScript-Webanwendungen durch den Googlebot durchläuft drei Hauptphasen:

  1. Crawlen
  2. Rendern
  3. Indexieren

Das heißt, der Googlebot crawlt, rendert und indexiert eine Seite.

Der Googlebot nimmt eine URL aus der Crawling-Warteschlange, crawlt sie und übergibt sie an die Verarbeitungsphase. In der Verarbeitungsphase werden Links extrahiert und wieder in die Crawling-Warteschlange gestellt. Außerdem wird die Seite zum Rendern in die Warteschlange gestellt. Die Seite wird aus der Rendering-Warteschlange an den Renderer übergeben, der den gerenderten HTML-Code wieder an die Verarbeitung übergibt. Dort werden die Inhalte indexiert und Links extrahiert, um sie in die Crawling-Warteschlange zu stellen.

Wenn der Googlebot mithilfe einer HTTP-Anfrage eine URL aus der Crawling-Warteschlange abruft, überprüft er zuerst, ob sie gecrawlt werden darf. Dazu liest er die robots.txt-Datei. Wenn du die URL dort als unzulässig gekennzeichnet hast, lässt der Googlebot die HTTP-Anfrage für diese URL aus.

Anschließend parst der Googlebot die Antwort für andere URLs im href-Attribut von HTML-Links und stellt diese URLs in die Crawling-Warteschlange. Du kannst bei Bedarf den nofollow-Mechanismus verwenden, um bestimmte Links auszuschließen.

Das Crawlen einer URL und das Parsen der HTML-Antwort funktioniert gut mit klassischen Websites oder serverseitig gerenderten Seiten, bei denen der HTML-Code in der HTTP-Antwort den gesamten Inhalt enthält. Für einige JavaScript-Websites wird möglicherweise das Anwendungsshell-Modell verwendet, bei dem der ursprüngliche HTML-Code nicht den tatsächlichen Inhalt enthält. Hier muss der Googlebot JavaScript ausführen, damit der tatsächliche, von JavaScript generierte Seiteninhalt angezeigt werden kann.

Der Googlebot stellt alle Seiten zum Rendern in die Warteschlange, es sei denn, er wird über ein Robots-Meta-Tag oder einen Header angewiesen, die Seite nicht zu indexieren. Die Seite verbleibt möglicherweise nur einige Sekunden in dieser Warteschlange, es kann jedoch auch länger dauern. Sobald die Ressourcen des Googlebot dies zulassen, rendert eine monitorlose Variante von Chromium die Seite und führt das JavaScript aus. Der Googlebot parst den gerenderten HTML-Code noch einmal nach Links und stellt die gefundenen URLs zum Crawlen in die Warteschlange. Außerdem verwendet er den gerenderten HTML-Code, um die Seite zu indexieren.

Serverseitiges oder Pre-Rendering ist trotzdem eine sehr gute Option, da deine Website dadurch für Nutzer und Crawler schneller wird und nicht alle Bots JavaScript ausführen können.

Seiten mit aussagekräftigen Titeln und Snippets beschreiben

Wenn du deiner Seite eindeutige, aussagekräftige Titel und sinnvolle Meta-Beschreibungen hinzufügst, können Nutzer schnell die gewünschten Inhalte finden. In unseren Richtlinien erläutern wir, was gute Titel und Beschreibungen ausmacht.

Um die Meta-Beschreibung und den Titel festzulegen oder zu ändern, kannst du JavaScript verwenden.

Kompatiblen Code schreiben

Browser bieten viele APIs und auch JavaScript als Sprache entwickelt und verändert sich rasch. Der Googlebot unterstützt nicht alle APIs und JavaScript-Funktionen. Führe unsere Anleitung zur Fehlerbehebung bei JavaScript-Problemen aus, um sicherzustellen, dass dein Code mit dem Googlebot kompatibel ist.

Aussagekräftige HTTP-Statuscodes verwenden

Mithilfe von HTTP-Statuscodes ermittelt der Googlebot, ob beim Crawlen der Seite ein Fehler aufgetreten ist.

Verwende einen aussagekräftigen Statuscode, um dem Googlebot mitzuteilen, ob eine Seite nicht gecrawlt oder indexiert werden soll, z. B. 404 für eine Seite, die nicht gefunden wurde, oder 401 für Seiten, die sich hinter einer Anmeldung befinden. Mithilfe von HTTP-Statuscodes kannst du dem Googlebot mitteilen, ob sich die URL einer Seite geändert hat, sodass der Index entsprechend aktualisiert werden kann.

HTTP-Statuscodes und ihre Verwendung:

HTTP-Status Verwendung
301/302 Die URL der Seite hat sich geändert.
401/403 Die Seite ist aufgrund von Berechtigungsproblemen nicht verfügbar.
404/410 Die Seite ist nicht mehr verfügbar.
5xx Serverseitig ist ein Fehler aufgetreten.

Soft 404-Fehler in Apps mit nur einer Seite vermeiden

Bei clientseitig gerenderten einseitigen Apps wird das Routing häufig als clientseitiges Routing implementiert. In diesem Fall ist die Verwendung aussagekräftiger HTTP-Statuscodes unter Umständen nicht möglich oder unpraktisch. Nutze eine der folgenden Strategien, um Soft 404-Fehler beim clientseitigen Rendering und Routing zu vermeiden:

  • Verwende eine JavaScript-Weiterleitung zu einer URL, auf die der Server mit dem HTTP-Statuscode 404 (z. B. /not-found) antwortet.
  • Füge <meta name="robots" content="noindex"> mithilfe von JavaScript zu Fehlerseiten hinzu.

Hier ist ein Beispielcode für die Weiterleitung:

fetch(`/api/products/${productId}`)
.then(response => response.json())
.then(product => {
  if(product.exists) {
    showProductDetails(product); // shows the product information on the page
  } else {
    // this product does not exist, so this is an error page.
    window.location.href = '/not-found'; // redirect to 404 page on the server.
  }
})

Hier ist ein Beispielcode für den noindex-Ansatz:

fetch(`/api/products/${productId}`)
.then(response => response.json())
.then(product => {
  if(product.exists) {
    showProductDetails(product); // shows the product information on the page
  } else {
    // this product does not exist, so this is an error page.
    // Note: This example assumes there is no other meta robots tag present in the HTML.
    const metaRobots = document.createElement('meta');
    metaRobots.name = 'robots';
    metaRobots.content = 'noindex';
    document.head.appendChild(metaRobots);
  }
})

History API anstelle von Fragmenten verwenden

Wenn der Googlebot auf deinen Seiten nach Links sucht, werden nur URLs im href-Attribut von HTML-Links berücksichtigt.

Verwende für Single-Page-Anwendungen mit clientseitigem Routing die History API, um das Routing zwischen verschiedenen Ansichten deiner Webanwendung zu implementieren. Damit der Googlebot Links finden kann, solltest du keine Fragmente verwenden, um unterschiedliche Seiteninhalte zu laden. Das folgende Beispiel ist nicht sinnvoll, da der Googlebot die Links nicht crawlt:

<nav>
  <ul>
    <li><a href="#/products">Our products</a></li>
    <li><a href="#/services">Our services</a></li>
  </ul>
</nav>

<h1>Welcome to example.com!</h1>
<div id="placeholder">
  <p>Learn more about <a href="#/products">our products</a> and <a href="#/services">our services</p>
</div>
<script>
window.addEventListener('hashchange', function goToPage() {
  // this function loads different content based on the current URL fragment
  const pageToLoad = window.location.hash.slice(1); // URL fragment
  document.getElementById('placeholder').innerHTML = load(pageToLoad);
});
</script>

Stattdessen solltest du sicherstellen, dass Link-URLs für den Googlebot zugänglich sind, indem du die History API implementierst:

<nav>
  <ul>
    <li><a href="/products">Our products</a></li>
    <li><a href="/services">Our services</a></li>
  </ul>
</nav>

<h1>Welcome to example.com!</h1>
<div id="placeholder">
  <p>Learn more about <a href="/products">our products</a> and <a href="/services">our services</p>
</div>
<script>
function goToPage(event) {
  event.preventDefault(); // stop the browser from navigating to the destination URL.
  const hrefUrl = event.target.getAttribute('href');
  const pageToLoad = hrefUrl.slice(1); // remove the leading slash
  document.getElementById('placeholder').innerHTML = load(pageToLoad);
  window.history.pushState({}, window.title, hrefUrl) // Update URL as well as browser history.
}

// Enable client-side routing for all links on the page
document.querySelectorAll('a').forEach(link => link.addEventListener('click', goToPage));

</script>

Meta-Robots-Tags mit Bedacht verwenden

Über das Meta-Robots-Tag kannst du den Googlebot daran hindern, eine Seite zu indexieren oder bestimmten Links zu folgen. Wenn du beispielsweise das folgende Meta-Tag oben auf deiner Seite einfügst, kann der Googlebot die Seite nicht indexieren:

<!-- Googlebot won't index this page or follow links on this page -->
<meta name="robots" content="noindex, nofollow">

Mit JavaScript kannst du einer Seite ein Meta-Robots-Tag hinzufügen oder den Seiteninhalt ändern. Der folgende Beispielcode zeigt, wie du das Meta-Robots-Tag mit JavaScript änderst, um die Indexierung der aktuellen Seite zu verhindern, wenn ein API-Aufruf keinen Inhalt zurückgibt.

fetch('/api/products/' + productId)
  .then(function (response) { return response.json(); })
  .then(function (apiResponse) {
    if (apiResponse.isError) {
      // get the robots meta tag
      var metaRobots = document.querySelector('meta[name="robots"]');
      // if there was no robots meta tag, add one
      if (!metaRobots) {
        metaRobots = document.createElement('meta');
        metaRobots.setAttribute('name', 'robots');
        document.head.appendChild(metaRobots);
      }
      // tell Googlebot to exclude this page from the index
      metaRobots.setAttribute('content', 'noindex');
      // display an error message to the user
      errorMsg.textContent = 'This product is no longer available';
      return;
    }
    // display product information
    // ...
  });
    

Wenn der Googlebot vor der Ausführung von JavaScript im Robots-Meta-Tag auf noindex stößt, wird die Seite weder gerendert noch indexiert.

Langlebiges Caching verwenden

Der Googlebot speichert offensiv im Cache, um Netzwerkanfragen und Ressourcennutzung zu reduzieren. Der WRS ignoriert Caching-Header möglicherweise. Dies kann dazu führen, dass WRS veraltete JavaScript- oder CSS-Ressourcen verwendet. Durch Inhalts-Fingerabdrücke wird dieses Problem vermieden, da ein Fingerabdruck des Inhalts Teil des Dateinamens wird, z. B. main.2bb85551.js. Der Fingerabdruck hängt vom Inhalt der Datei ab, sodass bei Aktualisierungen jedes Mal ein anderer Dateiname generiert wird. Weitere Informationen findest du im web.dev-Leitfaden zu langlebigen Caching-Strategien.

Strukturierte Daten verwenden

Wenn du auf deinen Seiten strukturierte Daten nutzt, kannst du JavaScript verwenden, um das erforderliche JSON-LD zu generieren und in die Seite einzufügen. Teste deine Implementierung, um Probleme zu vermeiden.

Den Best Practices für Webkomponenten folgen

Der Googlebot unterstützt Webkomponenten. Wenn der Googlebot eine Seite rendert, fasst er Shadow DOM- und Light DOM-Inhalte zusammen. Das bedeutet, dass der Googlebot nur Inhalte sehen kann, die im gerenderten HTML-Code sichtbar sind. Damit du sichergehen kannst, dass der Googlebot deine Inhalte nach dem Rendering noch sehen kann, verwende den Test auf Optimierung für Mobilgeräte oder das URL-Prüftool und sieh dir den gerenderten HTML-Code an.

Wenn der Inhalt im gerenderten HTML-Code nicht sichtbar ist, kann der Googlebot ihn nicht indexieren.

Im folgenden Beispiel wird eine Webkomponente erstellt, bei der die Light DOM-Inhalte innerhalb der Shadow DOM angezeigt werden. Eine Möglichkeit, dafür zu sorgen, dass sowohl die Light DOM- als auch die Shadow DOM-Inhalte im gerenderten HTML-Code angezeigt werden, ist die Verwendung eines Slot-Elements.

<script>
  class MyComponent extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });
    }

    connectedCallback() {
      let p = document.createElement('p');
      p.innerHTML = 'Hello World, this is shadow DOM content. Here comes the light DOM: <slot></slot>';
      this.shadowRoot.appendChild(p);
    }
  }

  window.customElements.define('my-component', MyComponent);
</script>

<my-component>
  <p>This is light DOM content. It's projected into the shadow DOM.</p>
  <p>WRS renders this content as well as the shadow DOM content.</p>
</my-component>
            

Nach dem Rendern indexiert der Googlebot diese Inhalte:

<my-component>
  Hello World, this is shadow DOM content. Here comes the light DOM:
  <p>This is light DOM content. It's projected into the shadow DOM<p>
  <p>WRS renders this content as well as the shadow DOM content.</p>
</my-component>
    

Probleme mit Bildern und Lazy-Load-Inhalten beheben

Bilder können in Bezug auf Bandbreite und Leistung sehr aufwendig sein. Mit Lazy Loading werden Bilder erst dann geladen, wenn sie den Darstellungsbereich erreichen. Wenn du Lazy Loading für die Suche einsetzen möchtest, empfehlen wir dir unsere Hinweise zur suchmaschinenfreundlichen Implementierung.