CMS headless et SEO : ce qui compte

headless-cms

« Si notre contenu vit dans une API, Google peut-il seulement le voir ? » Chaque équipe pose cette question avant de passer en headless, souvent parce que quelqu’un a vu en 2019 une application React rendue côté client servir une <div> vide à un robot d’exploration. La crainte est dépassée, mais la question en cache une vraie : en headless, la responsabilité du SEO passe du CMS à vous. Voici la carte de ce qui vous revient désormais.

La réponse courte

Les moteurs de recherche classent du HTML servi depuis des URL de votre domaine. Ils ne savent pas, et ne cherchent pas à savoir, si ce HTML a été assemblé à partir d’une base de données, d’une API ou de fichiers Markdown. Un site headless avec rendu côté serveur produit exactement le même résultat indexable qu’un CMS traditionnel, et souvent mieux, parce que vous contrôlez chaque octet de la page.

Tout tient dans la condition : avec rendu côté serveur. Choisissez le bon modèle de rendu, et le reste relève du SEO technique ordinaire.

Le rendu : la seule décision qui compte

Il y a trois façons de transformer le contenu d’une API en pages :

  • Rendu côté client (CSR) : le navigateur récupère du JSON et construit la page en JavaScript. Google sait exécuter le JavaScript, mais le rendu est différé, et les autres robots, les aperçus de liens et les scrapers des réseaux sociaux s’en sortent plus ou moins bien. Pour un contenu que vous voulez voir classé, le CSR est le choix risqué.

  • Rendu côté serveur (SSR) : votre serveur interroge l’API de contenu à chaque requête et renvoie du HTML fini. Toujours indexable ; la fraîcheur est automatique ; le coût est un appel par requête (mis en cache comme bon vous semble).

  • Génération statique (SSG) : les pages sont construites à l’avance et servies comme des fichiers. La livraison la plus rapide possible ; il faut reconstruire ou revalider quand le contenu change.

Tout framework moderne (Next.js, Astro, Nuxt, SvelteKit, TanStack Start) fait par défaut du SSR ou du SSG à partir d’une API de contenu, avec l’appel à l’API dans un loader ou au moment du build. Si vous ne retenez qu’une règle de cet article : les pages de contenu publiques sont rendues sur le serveur.

L’avantage du domaine dont personne ne parle

Passer en headless est souvent un gain pour le SEO, pour une raison structurelle : le contenu arrive sur votre domaine principal. Les plateformes hébergées de blog et de documentation vivent sur des sous-domaines ou sur leurs propres domaines, et l’autorité que gagnent vos articles s’accumule là-bas. En headless, /blog, /help et /changelog sont des sous-répertoires du domaine de votre produit : chaque backlink vers un article renforce toutes vos autres pages. Ce seul facteur pèse en général plus lourd que tous les détails de balises meta qui suivent.

La liste de contrôle qui vous revient

Un CMS traditionnel gère une partie de tout cela sans que vous le voyiez. Le headless vous le confie, mais il suffit de le configurer une fois dans une fonction utilitaire, puisque tout découle des mêmes réponses de l’API.

Métadonnées par page

Titre, meta description, balises Open Graph et Twitter, dates de l’article. Saisissez-les comme champs dans le CMS, à côté du contenu, et placez-les dans l’en-tête du document à partir du même appel qui rend la page. Avec un backend de contenu qui modélise des champs SEO par entrée (titre, description, image), c’est une simple correspondance, pas un projet.

URL canoniques

Chaque page déclare son URL canonique, calculée à partir du slug de l’entrée, jamais recopiée depuis l’URL de la requête : celle-ci rendrait canoniques les variantes ?utm_source= et les accidents de casse. Une seule fonction qui associe une entrée à son chemin, utilisée par les pages, le sitemap et les flux, garantit qu’ils ne se contredisent jamais.

De vrais codes de statut

Un slug inconnu doit renvoyer un code HTTP 404, pas une page d’erreur mise en forme avec un statut 200. Les soft 404 gaspillent le budget de crawl et polluent l’index. De même, si votre route serveur n’arrive pas à joindre l’API de contenu, renvoyez un 5xx avec Cache-Control: no-store au lieu de mettre en cache un 200 vide sur votre CDN.

Sitemap et flux

Générez sitemap.xml à partir des mêmes endpoints de liste que vos pages d’index, avec un vrai lastmod tiré des dates des entrées. Ajoutez un flux RSS pour le blog et le journal des modifications : un flux ne coûte presque rien, et les lecteurs comme les robots s’en servent.

Données structurées

Générez le JSON-LD (Article pour les articles, FAQPage quand c’est pertinent, Organization sur la page d’accueil) à partir des données de l’entrée. Une subtilité quand vous injectez du JSON-LD depuis le code serveur : échappez chaque < du JSON sérialisé en \\u003c, pour qu’un </script> égaré dans un titre ne puisse pas sortir de la balise script.

Désindexer ce qui ne doit pas se classer

Les pages de résultats de recherche, les routes de prévisualisation et les combinaisons paginées de tags méritent souvent un noindex. Si votre plateforme propose un portail hébergé sur son propre domaine en plus de la livraison par API, vérifiez comment elle gère l’indexation. Les pages du portail hébergé de Kookee sont volontairement en noindex : seule la version rendue sur votre propre domaine est en concurrence dans les résultats, sans ambiguïté de contenu dupliqué.

Fraîcheur et discipline de cache

En SSR, les modifications publiées sont en ligne dès la requête suivante. En SSG, fixez pour chaque type de contenu le retard que vous acceptez : un blog peut se reconstruire sans se presser ; un journal des modifications ou une page liée à l’état du service demande une revalidation qui se compte en minutes. Dans les deux cas, mettez en cache sur votre CDN de façon délibérée : des clés de cache sur l’URL, des TTL raisonnables, et une purge à la publication si votre plateforme propose des webhooks ou si vous relancez un build à chaque publication.

Contenu multilingue

Si vous servez plusieurs langues, le headless offre là encore la version propre : récupérez les traductions de l’entrée depuis l’API, servez chaque langue à sa propre URL et générez les balises hreflang à partir de la liste des traductions. En revanche, il ne vous protège pas d’une traduction automatique bâclée : ne publiez que les langues que vous entretenez.

Un test à faire aujourd’hui

Prenez votre page la plus importante et vérifiez, JavaScript désactivé : le texte complet apparaît-il dans le code source HTML ? Le titre, la description et l’URL canonique correspondent-ils à cette page ? Un slug fantaisiste renvoie-t-il un 404 ? Ouvrez sitemap.xml : la page y figure-t-elle avec un lastmod plausible ? Quinze minutes, et vous couvrez 90 % de ce qui tourne mal.

Le headless ne nuit pas au SEO. Le JavaScript non rendu nuit au SEO, les mauvais codes de statut nuisent au SEO, et les sous-domaines des fournisseurs le taxent en silence. Choisissez le rendu côté serveur, tirez chaque signal des données des entrées que vous récupérez déjà, et gardez l’autorité sur le seul domaine qui devrait la gagner : le vôtre.