Comprendre les bases du SEO JavaScript

JavaScript joue un rôle crucial dans la plate-forme Web. En effet, ses nombreuses fonctionnalités lui permettent de convertir le Web en une plate-forme applicative puissante. En permettant à la recherche Google d'accéder à vos applications JavaScript, vous pouvez non seulement attirer de nouveaux utilisateurs, mais aussi accroître l'engagement avec les utilisateurs existants lorsqu'ils recherchent du contenu fourni par une ou plusieurs de vos applications. Bien que la recherche Google utilise JavaScript avec une version toujours actualisée de Chromium, plusieurs optimisations sont possibles.

Ce guide décrit comment la recherche Google traite JavaScript et partage des bonnes pratiques permettant d'améliorer la visibilité des applications Web JavaScript dans la recherche Google.

Comment Googlebot traite-t-il JavaScript ?

Googlebot traite les applications Web JavaScript en trois phases principales :

  1. Exploration
  2. Affichage
  3. Indexation

Googlebot explore, affiche et indexe les pages.

Googlebot extrait une URL de la file d'attente d'exploration, l'explore, puis l'envoie en phase de traitement. La phase de traitement extrait les liens qui remontent dans la file d'attente d'exploration, puis met la page en file d'attente pour l'affichage. La page passe de la file d'attente d'affichage au moteur de rendu, qui renvoie le code HTML affiché à la phase de traitement, qui indexe le contenu et extrait les liens avant de les placer dans la file d'attente d'exploration.

Lorsque Googlebot extrait une URL de la file d'attente d'exploration via une requête HTTP, il vérifie d'abord si vous en autorisez l'exploration. Googlebot lit alors le fichier robots.txt. Si l'URL est marquée comme non autorisée, Googlebot n'envoie pas la requête HTTP pour cette URL et ignore cette dernière.

Googlebot analyse ensuite la réponse pour les autres URL dans l'attribut href des liens HTML, puis ajoute les URL à la file d'attente d'exploration. Pour empêcher la découverte de liens, utilisez le mécanisme nofollow.

L'exploration d'une URL et l'analyse de la réponse HTML conviennent particulièrement aux sites Web classiques ou aux pages affichées côté serveur dans lesquelles le code HTML de la réponse HTTP inclut tout le contenu. Certains sites JavaScript utilisent le modèle "shell d'application". Dans ce cas, le code HTML initial ne comporte pas le contenu réel, et Googlebot doit exécuter JavaScript avant de pouvoir lire le contenu de la page générée par JavaScript.

Googlebot met toutes les pages en file d'attente pour l'affichage, sauf si un en-tête ou une balise Meta pour les robots indique à Googlebot de ne pas indexer la page. La page peut rester dans cette file d'attente pendant quelques secondes ou pendant plus de temps. Une fois que les ressources de Googlebot le permettent, l'environnement Chromium sans interface graphique affiche la page et exécute le code JavaScript. Googlebot recherche à nouveau les liens dans le code HTML affiché, puis met les URL en file d'attente pour l'exploration. Googlebot utilise également le code HTML affiché pour indexer la page.

Gardez à l'esprit que l'affichage côté serveur ou le pré-affichage est recommandé, car il permet aux utilisateurs et aux robots d'exploration d'accéder à votre site plus rapidement. De plus, tous les robots n'utilisent pas forcément JavaScript.

Décrire votre page avec des titres et des extraits uniques

Le recours à des titres uniques et descriptifs, ainsi qu'à des meta descriptions utiles aide les utilisateurs à identifier rapidement le résultat le plus adapté à leur objectif. Pour en savoir plus, reportez-vous à ces consignes.

Vous pouvez utiliser JavaScript pour définir ou modifier la méta description et le titre.

S'assurer que le code est compatible

Les navigateurs proposent de nombreuses API, et le langage JavaScript évolue rapidement. Googlebot impose certaines limitations concernant les API et les fonctionnalités JavaScript acceptées. Pour vous assurer que le code est compatible avec Googlebot, suivez les instructions permettant de résoudre les problèmes liés à JavaScript.

Utiliser des codes d'état HTTP adéquats

Googlebot utilise les codes d'état HTTP pour déterminer si une erreur s'est produite lors de l'exploration de la page.

Vous devez utiliser un code d'état adéquat pour indiquer à Googlebot si une page ne doit pas être explorée ou indexée (code 404 pour une page introuvable ou code 401 pour les pages protégées par des identifiants de connexion, par exemple). Vous pouvez utiliser des codes d'état HTTP pour indiquer à Googlebot si une page a été migrée vers une nouvelle URL. L'index pourra ainsi être mis à jour en conséquence.

Voici une liste des codes d'état HTTP accompagnés d'une description des cas d'utilisation possibles :

État HTTP Cas d'utilisation
301/302 La page a été migrée vers une nouvelle URL.
401/403 La page n'est pas disponible en raison de problèmes d'autorisations.
404/410 La page n'est plus disponible.
5xx Une erreur s'est produite côté serveur.

Éviter les erreurs 404 dans les applications à page unique

Dans les applications à page unique affichées côté client, le routage est souvent mis en œuvre du côté du client. Dans ce cas, l'utilisation de codes d'état HTTP adéquats peut se révéler impossible ou difficilement applicable. Pour éviter les erreurs de type "erreur 404" lors de l'affichage et du routage côté client, optez pour l'une des stratégies suivantes :

  • Utilisez une redirection JavaScript vers une URL pour laquelle le serveur répond avec un code d'état HTTP 404 (par exemple, /not-found).
  • Ajoutez une balise <meta name="robots" content="noindex"> aux pages d'erreur à l'aide de JavaScript.

Voici un exemple de code si vous optez pour la redirection :

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.
  }
})

Voici un exemple de code pour si vous optez pour une balise noindex :

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);
  }
})

Utiliser History API plutôt que des fragments

Lorsque Googlebot recherche des liens dans vos pages, il ne prend en compte que les URL qui se trouvent dans l'attribut href des liens HTML.

Pour les applications à page unique avec routage côté client, utilisez History API pour mettre en œuvre le routage entre différentes vues de votre application Web. Pour que Googlebot puisse identifier les liens, évitez d'utiliser des fragments pour charger différents contenus de la page. L'exemple suivant illustre ce qu'il est déconseillé de faire, car Googlebot n'explorera pas les liens :

<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>

À la place, mettez en œuvre History API pour vous assurer que Googlebot a accès aux URL des liens :

<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>

Utiliser les balises Meta pour les robots avec précaution

Vous pouvez empêcher Googlebot d'indexer une page ou de suivre des liens via une balise Meta pour les robots. Par exemple, l'ajout de la balise Meta suivante en haut de la page empêche Googlebot d'indexer cette dernière :

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

Vous pouvez utiliser JavaScript pour ajouter une balise Meta pour les robots à une page ou pour modifier son contenu. L'exemple de code suivant montre comment remplacer la balise Meta pour les robots par un code JavaScript pour empêcher l'indexation de la page active si un appel d'API ne renvoie pas de contenu.

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
    // ...
  });
    

Lorsque Googlebot identifie la directive noindex dans la balise Meta pour les robots, il ne procède ni à son affichage, ni à son indexation.

Utiliser la mise en cache de longue durée

Googlebot met le contenu en cache de manière intensive afin de limiter les demandes réseau et l'utilisation des ressources. WRS peut ignorer les en-têtes de mise en cache. Cela peut entraîner l'utilisation de ressources JavaScript ou CSS obsolètes par WRS. L'empreinte du contenu évite ce problème en effectuant une empreinte du nom de fichier, par exemple main.2bb85551.js. L'empreinte dépend du contenu du fichier. Par conséquent, les mises à jour génèrent un nom de fichier différent à chaque fois. Pour en savoir plus, consultez le guide web.dev sur les stratégies de mise en cache de longue durée.

Utiliser les données structurées

Lorsque vous utilisez des données structurées dans vos pages, vous pouvez utiliser JavaScript pour générer le fichier JSON-LD et l'injecter dans la page. Assurez-vous de tester votre mise en œuvre pour éviter tout problème.

Suivre les bonnes pratiques relatives aux composants Web

Googlebot est compatible avec les composants Web. Lorsqu'il affiche une page, il regroupe les contenus Light DOM et Shadow DOM. En d'autres termes, Googlebot ne voit que le contenu visible dans le rendu HTML. Pour vous assurer que Googlebot continue de voir votre contenu après son rendu, utilisez l'outil de test d'optimisation mobile ou l'outil d'inspection d'URL.

Si le contenu n'est pas visible dans le rendu HTML, Googlebot ne peut pas l'indexer.

L'exemple suivant crée un composant Web qui affiche son contenu Light DOM dans son composant Shadow DOM. Pour vous assurer que les contenus Light DOM et Shadow DOM apparaissent dans le rendu HTML, vous devez utiliser un élément Slot.

<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>
            

Après le rendu, Googlebot indexe le contenu suivant :

<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>
    

Résoudre les problèmes liés aux images et au chargement différé du contenu

Les images consomment souvent beaucoup de bande passante et peuvent nuire aux performances. Une bonne stratégie consiste à recourir au chargement différé afin de ne charger les images que lorsque l'utilisateur est sur le point de les consulter. Pour vous assurer que vous mettez en œuvre la fonctionnalité de chargement différé sans affecter l'expérience de recherche des internautes, suivez ces consignes.