Problèmes d'indexation en headless PrestaShop : diagnostic et solutions

Problèmes d'indexation en headless PrestaShop : diagnostic et solutions
Front rapide, trafic organique en chute : en PrestaShop headless, les problèmes d'indexation sont silencieux. HTML brut vs rendu, canonicals incohérentes, soft 404, sitemap désynchronisé : la méthode de diagnostic et les solutions concrètes côté Next.js.

Vous avez migré PrestaShop en headless, le front est rapide, l'UX est moderne — et pourtant le trafic organique chute. En architecture découplée, les problèmes d'indexation sont silencieux : aucune erreur visible, juste des pages qui disparaissent des SERP. Voici une méthode de diagnostic structurée et les solutions concrètes.

Les symptômes d'un problème d'indexation

Avant de plonger dans les outils, sachez reconnaître les signaux. En headless PrestaShop, un problème d'indexation se manifeste rarement par une erreur frontale :

  • Baisse du nombre de pages indexées dans Search Console sans déindexation volontaire
  • Augmentation des "Découvertes, actuellement non indexées" : Google connaît l'URL mais ne l'indexe pas
  • Fiches produit absentes des résultats alors qu'elles s'affichent correctement dans le navigateur
  • Décalage prix/stock dans les SERP : Google indexe une version périmée rendue côté client

Le piège du headless, c'est que tout fonctionne pour l'utilisateur humain. Le navigateur exécute le JavaScript, hydrate la page, affiche le contenu. Googlebot, lui, peut s'arrêter au HTML initial vide.

Étape 1 — Comparer HTML brut et HTML rendu

Le diagnostic fondamental : que voit un crawler qui n'exécute pas (ou tarde à exécuter) JavaScript ? Comparez les deux versions de la page.

# 1. HTML brut envoyé par le serveur (ce que Googlebot reçoit en premier)
curl -s -A "Googlebot" https://shop.example.com/produit/mon-produit \
  | grep -E '<(title|h1)|"price"|product:price'

# Si title, h1 et prix sont absents → contenu CSR-only, problème critique
# Si tout est présent → le HTML initial est correct, chercher ailleurs

Croisez ce résultat avec l'outil Inspection d'URL de Google Search Console. La capture "Page rendue" et l'onglet "HTML" montrent exactement ce que Googlebot a stocké. Si le HTML rendu contient le contenu mais pas le HTML téléchargé, vous dépendez de la seconde vague de crawl — un délai de plusieurs jours, inacceptable pour un catalogue qui change quotidiennement.

Étape 2 — Auditer les directives d'indexation

En headless, les balises meta robots et canonical sont générées par le front (Next.js, Nuxt…), plus par PrestaShop. Une incohérence se glisse facilement entre l'API et le rendu.

# Vérifier les directives sur un échantillon de pages
for url in \
  "https://shop.example.com/produit/produit-a" \
  "https://shop.example.com/categorie/chaussures" \
  "https://shop.example.com/categorie/chaussures?page=2"; do
  echo "=== $url ==="
  curl -s -A "Googlebot" "$url" \
    | grep -iE 'rel="canonical"|name="robots"'
done

Les erreurs les plus fréquentes à traquer :

  • Canonical pointant vers l'API au lieu de l'URL front (ex : api.shop.com au lieu de shop.com)
  • noindex hérité d'un environnement de staging et oublié en production
  • Canonical auto-référente cassée sur les pages paginées ou filtrées
  • Trailing slash incohérent entre le canonical et l'URL réelle, générant des doublons

Dans Next.js App Router, centralisez la génération des metadata côté serveur pour garantir la cohérence :

// app/produit/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
  const product = await getProductBySlug(params.slug);

  if (!product || !product.active) {
    return { robots: { index: false, follow: false } };
  }

  const canonicalUrl = `https://shop.example.com/produit/${product.link_rewrite}`;

  return {
    title: product.meta_title || product.name,
    description: product.meta_description,
    alternates: { canonical: canonicalUrl },
    robots: { index: true, follow: true },
  };
}

Étape 3 — Vérifier les codes HTTP

Un produit supprimé du catalogue PrestaShop doit renvoyer un vrai code HTTP — pas une page React affichant "produit introuvable" avec un statut 200. C'est l'erreur de soft 404 la plus courante en headless.

# Un produit désactivé doit répondre 404 ou 410, jamais 200
curl -s -o /dev/null -w "%{http_code}\n" \
  https://shop.example.com/produit/produit-supprime

# 200 → soft 404, Google garde la page en index et gaspille du crawl budget
# 404/410 → comportement correct
// app/produit/[slug]/page.tsx
import { notFound } from 'next/navigation';

export default async function ProductPage({ params }) {
  const product = await getProductBySlug(params.slug);

  // Déclenche un vrai 404 HTTP, pas une page de contenu
  if (!product || !product.active) {
    notFound();
  }

  return <ProductDetail product={product} />;
}

Étape 4 — Synchroniser le sitemap avec le catalogue

En headless, le sitemap est souvent généré à part du catalogue PrestaShop. Résultat : il liste des produits désactivés ou oublie les nouveaux. Un sitemap désynchronisé envoie de mauvais signaux à Google.

La bonne pratique : générer le sitemap dynamiquement depuis la source de vérité (l'API PrestaShop), en ne listant que les produits actifs et indexables.

// app/sitemap.ts — généré à la demande, toujours à jour
import { MetadataRoute } from 'next';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const products = await fetchProducts({ active: true, indexable: true });

  return products.map((product) => ({
    url: `https://shop.example.com/produit/${product.link_rewrite}`,
    lastModified: new Date(product.date_upd),
    changeFrequency: 'weekly',
    priority: 0.8,
  }));
}

Pour les gros catalogues, segmentez le sitemap (un index + plusieurs fichiers de 50 000 URLs max) afin de faciliter le suivi de l'indexation par segment dans Search Console.

Étape 5 — Mettre en place un monitoring continu

Le diagnostic ponctuel ne suffit pas : un déploiement peut réintroduire un noindex ou casser le rendu serveur. Automatisez la surveillance des pages critiques.

#!/bin/bash
# monitor-indexation.sh — à lancer en CI ou en cron
URLS=(
  "https://shop.example.com/produit/best-seller-1"
  "https://shop.example.com/categorie/nouveautes"
)

for url in "${URLS[@]}"; do
  html=$(curl -s -A "Googlebot" "$url")

  # Le H1 doit être dans le HTML initial
  echo "$html" | grep -q "<h1" || echo "ALERTE: H1 absent sur $url"

  # Aucun noindex inattendu
  echo "$html" | grep -qi 'name="robots"[^>]*noindex' \
    && echo "ALERTE: noindex détecté sur $url"
done

Complétez avec l'API Search Console (URL Inspection) pour récupérer programmatiquement le statut d'indexation réel de Google sur vos URLs prioritaires, et déclencher une alerte dès qu'une page passe en "non indexée".

Checklist de résolution

  • Le HTML brut (curl Googlebot) contient titre, H1, description et prix sur les pages produit
  • Les canonicals pointent vers l'URL front publique, jamais vers l'API ni le staging
  • Aucun noindex résiduel hérité d'un environnement de test
  • Les produits supprimés/désactivés renvoient un 404 ou 410, pas un 200
  • Le sitemap est généré depuis l'API et ne liste que des produits actifs
  • Un monitoring automatisé vérifie le rendu serveur à chaque déploiement
  • L'API Search Console alerte sur les passages en "non indexé"

Conclusion

En PrestaShop headless, l'indexation ne se règle pas une fois pour toutes : c'est un système à surveiller. La cause racine est presque toujours la même — un écart entre ce que voit l'utilisateur et ce que reçoit Googlebot. Le réflexe à ancrer : pour chaque page SEO-critique, le contenu, les directives et le bon code HTTP doivent être présents dans la réponse HTTP initiale du serveur, sans dépendre de JavaScript. Le reste n'est que de l'instrumentation pour détecter les régressions avant Google.

Votre front headless perd des positions sans explication ? Contactez-moi pour un diagnostic d'indexation de votre architecture découplée.

Jonathan Le-Peru

Écrit par Jonathan Le-Peru

Développeur backend avec plus de 7 ans d'expérience, spécialisé dans la création de solutions e-commerce robustes avec Prestashop. Passionné par l'optimisation des performances et les bonnes pratiques de développement.