John Mueller vient de publier une liste de neuf scénarios concrets qui expliquent comment Google sélectionne l'URL canonique d'un contenu. Ce n'est pas une nouveauté théorique — c'est la première fois que Google formalise aussi clairement les cas de figure où votre rel=canonical sera ignoré au profit d'un autre signal. Pour quiconque gère un site au-delà de quelques centaines de pages, chaque scénario décrit un piège technique réel.
Le rel=canonical est un hint, pas une directive
La confusion persiste : beaucoup de développeurs traitent rel=canonical comme une instruction ferme. C'est faux. Google le classe explicitement comme un signal parmi d'autres, au même titre que les redirections, les sitemaps, les liens internes et le contenu de la page elle-même.
La documentation officielle de Google sur la canonicalisation utilise le terme "hint" — un indice. Quand plusieurs signaux se contredisent, Google tranche selon sa propre logique. Et c'est précisément ce que les 9 scénarios de Mueller détaillent.
Pourquoi Google ignore-t-il vos canonicals ?
Le moteur agrège plusieurs signaux pour déterminer quelle URL "mérite" d'être la référence :
- La balise
rel=canonicaldans le<head> - L'en-tête HTTP
Link: rel=canonical - Les redirections 301/302
- Les URL déclarées dans le sitemap XML
- Les liens internes (quelle variante reçoit le plus de liens ?)
- Le contenu de la page (identique, quasi-identique, ou différent ?)
- Le protocole (HTTP vs HTTPS)
- La présence ou absence de
www
Quand ces signaux s'alignent, tout va bien. Quand ils divergent, Google choisit — et son choix ne sera pas toujours celui que vous attendez.
Le cas classique du e-commerce multi-facettes
Prenez un site e-commerce de 18 000 pages produit, avec des filtres de recherche qui génèrent des URL paramétrées. La page produit "Chaussures running homme Nike" existe sous :
<!-- Page principale -->
<link rel="canonical" href="https://shop.example.fr/chaussures/running-homme-nike" />
<!-- Variantes paramétrées qui pointent vers la même canonical -->
https://shop.example.fr/chaussures/running-homme-nike?color=noir
https://shop.example.fr/chaussures/running-homme-nike?size=42&color=noir
https://shop.example.fr/chaussures?brand=nike&category=running&gender=homme
Si le sitemap XML déclare l'URL paramétrée, si les liens internes pointent majoritairement vers la version avec paramètres, et si la navigation à facettes génère plus de maillage vers ?brand=nike&category=running que vers le slug propre — Google peut parfaitement ignorer votre canonical et indexer la version paramétrée.
Les 9 scénarios décortiqués techniquement
Reprenons les scénarios listés par Mueller et analysons chacun avec le niveau de détail qu'un Lead SEO attend.
Scénario 1 : Redirection vs canonical contradictoire
L'URL A redirige en 301 vers l'URL B, mais l'URL B déclare l'URL C comme canonical. Google doit trancher entre le signal de redirection (A → B) et le signal canonical (B → C). Dans la majorité des cas observés, la chaîne de redirection l'emporte si elle est cohérente et ancienne. Mais si C est clairement la page la plus liée et la plus présente dans le sitemap, Google peut suivre la canonical.
Recommandation : ne créez jamais de contradiction entre vos redirections et vos canonicals. Vérifiez avec Screaming Frog en lançant un crawl avec le mode "Follow canonical" activé :
# Export Screaming Frog CLI pour détecter les conflits redirect/canonical
screamingfrogseospider --crawl https://shop.example.fr \
--headless \
--export-tabs "Redirects:All,Canonicals:All" \
--output-folder /tmp/audit-canonicals/
Croisez ensuite les deux exports : toute URL qui apparaît comme destination de redirect ET dont la canonical pointe ailleurs est un conflit à résoudre.
Scénario 2 : HTTPS vs HTTP
Google préfère HTTPS. Si les deux versions d'une page existent et que la version HTTP ne redirige pas proprement vers HTTPS, Google choisira HTTPS comme canonical — même si la page HTTP déclare une canonical vers elle-même.
Ce scénario est courant après une migration HTTP vers HTTPS incomplète. Le piège : les redirections sont en place sur le serveur principal, mais un CDN ou un reverse proxy sert encore du HTTP sur certains chemins.
Scénario 3 : www vs non-www
Identique au scénario HTTPS/HTTP en logique. Google choisit la variante la plus cohérente avec le reste des signaux. Si votre sitemap déclare www.example.fr, que vos liens internes utilisent www.example.fr, mais que votre canonical dit example.fr — vous envoyez des signaux contradictoires.
Scénario 4 : URL dans le sitemap vs canonical déclarée
Un signal sous-estimé. Google accorde du poids aux URL listées dans le sitemap XML. Si votre sitemap contient https://shop.example.fr/produit/123 mais que la page déclare une canonical vers https://shop.example.fr/produit/chaussure-nike-air, Google doit résoudre le conflit.
Voici une config Nginx qui force la cohérence entre URL servie et sitemap en redirigeant les variantes numériques :
# Redirection des anciennes URL numériques vers les slugs SEO-friendly
location ~ ^/produit/(\d+)$ {
# Lookup dans une map ou un backend pour résoudre l'ID vers le slug
# Ici, simplifié avec une map statique
set $new_slug "";
if ($1 = "123") {
set $new_slug "chaussure-nike-air";
}
if ($new_slug != "") {
return 301 https://shop.example.fr/produit/$new_slug;
}
# Si pas de mapping trouvé, 404
return 404;
}
Scénario 5 : Contenu dupliqué sur des URL différentes
Le scénario le plus fréquent à grande échelle. Deux URL servent un contenu identique ou quasi-identique sans aucune balise canonical, sans redirection, et toutes deux sont dans le sitemap. Google doit deviner laquelle est la "bonne".
Les signaux de départage : volume de liens internes, ancienneté de l'URL, liens externes, performances de l'URL dans les résultats de recherche.
Scénario 6 : Canonical pointant vers une page 404 ou non-indexable
Si votre rel=canonical pointe vers une URL qui retourne un 404, un noindex, ou une 5xx, Google l'ignore et sélectionne l'URL courante (ou une autre variante) comme canonical. C'est un scénario fréquent post-refonte de site quand les anciennes URL canoniques n'existent plus.
Scénario 7 : Canonical auto-référente absente
Quand une page ne déclare aucune canonical, Google utilise les autres signaux pour en déduire une. L'absence de canonical auto-référente n'est pas une erreur en soi, mais elle laisse plus de latitude à Google pour choisir une URL que vous n'avez pas prévue — surtout si des paramètres de tracking (utm_source, fbclid) créent des variantes.
Scénario 8 : Pages paginées avec canonicals mal configurées
Les pages 2, 3, 4… d'une liste produit qui déclarent toutes une canonical vers la page 1. Google a explicitement dit que ce pattern est incorrect : chaque page paginée doit avoir une canonical auto-référente. Sinon, seule la page 1 sera indexée, et les produits des pages suivantes disparaissent de l'index.
Scénario 9 : Hreflang et canonical en conflit
Dans un contexte multilingue, la page FR déclare une canonical vers elle-même ET un hreflang vers la page EN. Mais la page EN déclare une canonical vers la page FR. Google ne peut pas résoudre cette boucle. Le résultat : il ignore le hreflang et choisit la canonical qu'il estime la plus pertinente — souvent la version dans la langue la plus populaire pour la requête.
Diagnostic technique : détecter les conflits de canonical à grande échelle
Sur un site de 500 pages, un audit manuel suffit. Sur 15 000 pages, il faut automatiser. Voici un pipeline de diagnostic complet.
Étape 1 : Extraire les canonicals déclarées via crawl
Screaming Frog reste l'outil de référence pour l'extraction. Mais sur de gros volumes, un crawl programmatique avec Python est plus flexible :
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse
import csv
def audit_canonicals(urls: list[str], output_file: str):
"""
Pour chaque URL, vérifie la cohérence entre :
- l'URL crawlée
- la canonical HTML
- la canonical HTTP header
- le status code
"""
results = []
for url in urls:
try:
resp = requests.get(url, timeout=10, allow_redirects=True)
final_url = resp.url # URL après redirections
status = resp.status_code
# Canonical depuis le header HTTP
link_header = resp.headers.get("Link", "")
http_canonical = None
if 'rel="canonical"' in link_header:
http_canonical = link_header.split(";")[0].strip("<>")
# Canonical depuis le HTML
soup = BeautifulSoup(resp.text, "html.parser")
link_tag = soup.find("link", {"rel": "canonical"})
html_canonical = link_tag["href"] if link_tag else None
# Détection des conflits
conflict = "NONE"
if html_canonical and http_canonical and html_canonical != http_canonical:
conflict = "HTML_VS_HTTP_HEADER"
elif html_canonical and html_canonical != final_url:
conflict = "CANONICAL_DIFFERS_FROM_URL"
elif not html_canonical:
conflict = "MISSING_CANONICAL"
results.append({
"requested_url": url,
"final_url": final_url,
"status": status,
"html_canonical": html_canonical,
"http_canonical": http_canonical,
"conflict": conflict,
})
except Exception as e:
results.append({
"requested_url": url,
"final_url": None,
"status": "ERROR",
"html_canonical": None,
"http_canonical": None,
"conflict": f"FETCH_ERROR: {e}",
})
with open(output_file, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=results[0].keys())
writer.writeheader()
writer.writerows(results)
conflicts = [r for r in results if r["conflict"] != "NONE"]
print(f"Audit terminé : {len(conflicts)} conflits sur {len(results)} URLs")
# Usage avec les URLs extraites du sitemap
from xml.etree import ElementTree
sitemap_resp = requests.get("https://shop.example.fr/sitemap.xml")
tree = ElementTree.fromstring(sitemap_resp.content)
ns = {"s": "http://www.sitemaps.org/schemas/sitemap/0.9"}
urls = [loc.text for loc in tree.findall(".//s:loc", ns)]
audit_canonicals(urls, "canonical_audit.csv")
Ce script détecte les quatre cas problématiques : canonical manquante, canonical différente de l'URL servie, conflit entre canonical HTML et header HTTP, erreur de fetch.
Étape 2 : Croiser avec Google Search Console
L'onglet "Indexation des pages" dans Google Search Console montre les URL que Google a choisies comme canoniques. Exportez ce rapport et croisez-le avec votre audit :
- URL déclarée canonical = URL indexée par Google → OK
- URL déclarée canonical ≠ URL indexée par Google → Google a ignoré votre canonical
- URL non indexée, raison "Autre page canonical" → Google a élu une autre URL
Ce croisement révèle les vrais désaccords entre votre intention et le choix de Google. Sur un site e-commerce de 15 000 pages, il n'est pas rare de trouver 8 à 15% d'URLs où Google a choisi une canonical différente de celle déclarée.
Étape 3 : Monitoring continu
L'audit ponctuel ne suffit pas. Une mise à jour de template, un déploiement qui casse le SSR, un changement de framework — tout cela peut introduire des régressions sur les canonicals du jour au lendemain. Un outil de monitoring comme Seogard détecte ces régressions en temps réel : si une canonical disparaît ou change sur un batch de pages, vous recevez une alerte avant que Google ne recrawle.
Scénario réel : migration SSR et canonicals cassées
Un média en ligne de 12 000 articles migre d'un headless CMS avec rendu côté client (CSR) vers un setup Next.js avec SSR. Avant la migration, les canonicals étaient injectées côté client via JavaScript. Googlebot les rendait correctement — le rendering budget étant suffisant pour ce volume.
Après la migration vers SSR, l'équipe dev a oublié de porter le composant <Head> qui injectait la balise canonical. Résultat : pendant 11 jours, les 12 000 pages ont été servies sans aucune canonical déclarée.
L'impact observé
- Jours 1-3 : rien de visible. Google n'a pas encore recrawlé massivement.
- Jours 4-7 : le crawl rate augmente (Google détecte le changement de stack et recrawle plus agressivement). Les pages sont indexées sans canonical.
- Jours 8-11 : Google commence à sélectionner ses propres canonicals. Pour 1 400 articles, il choisit des URL avec paramètres de tracking (
?utm_source=newsletter) qui avaient été crawlées via des liens dans des emails indexés par des webmails publics. - Impact trafic : -23% de trafic organique sur les 1 400 articles affectés, car Google a dilué les signaux entre la "vraie" URL et la variante UTM.
La correction
// components/SEOHead.tsx — Next.js App Router
import { headers } from 'next/headers';
export default function SEOHead({
title,
description,
canonicalPath
}: {
title: string;
description: string;
canonicalPath: string;
}) {
// Construire la canonical à partir du path, jamais depuis l'URL courante
// pour éviter d'inclure des paramètres de tracking
const baseUrl = 'https://media.example.fr';
const canonical = `${baseUrl}${canonicalPath}`;
return (
<>
<title>{title}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonical} />
</>
);
}
Le point clé : la canonical est construite à partir d'un canonicalPath stocké en base de données, jamais dérivée de l'URL de la requête HTTP entrante. C'est la seule façon d'éviter que des paramètres de query string se glissent dans la canonical.
Après correction et soumission d'un recrawl via Search Console (Inspection d'URL > Demander l'indexation pour les pages critiques, puis un nouveau sitemap ping), le trafic est revenu à son niveau initial en 18 jours.
Les signaux que Google pondère le plus (par ordre d'importance observé)
Google n'a jamais publié de hiérarchie officielle des signaux de canonicalisation. Mais en croisant les déclarations de Mueller, la documentation officielle, et les observations à grande échelle sur des centaines de sites, un ordre de priorité se dessine :
- Redirections 301 — le signal le plus fort. Une 301 est quasi-toujours respectée comme signal canonical.
- Canonical HTML + header HTTP cohérents — quand les deux sont présents et concordants, Google les suit dans la grande majorité des cas.
- URL dans le sitemap XML — poids modéré, mais c'est un départageur quand les autres signaux sont ambigus.
- Liens internes — la variante qui reçoit le plus de maillage interne est favorisée. C'est un signal souvent sous-estimé.
- HTTPS > HTTP — préférence systématique sauf si tous les autres signaux pointent vers HTTP.
- Liens externes — si une variante a significativement plus de backlinks, elle peut l'emporter.
Le piège des redirections 302
Les 302 (redirect temporaire) sont un cas ambivalent. Google a confirmé que les 302 transmettent les signaux de ranking comme les 301 dans la plupart des cas. Mais pour la canonicalisation spécifiquement, une 302 longue durée (plus de quelques semaines) sera traitée comme une 301 de facto. Le risque : pendant la période d'ambiguïté, Google peut hésiter entre les deux URL.
Règle simple : si la redirection est permanente, utilisez 301. Toujours. Les tests A/B sont le seul cas légitime de 302 durable.
Edge cases et trade-offs à connaître
Pages avec contenu rendu en JavaScript
Si votre canonical est injectée par JavaScript et que Googlebot ne rend pas la page (timeout, erreur JS, dépassement du rendering budget), la canonical n'existe pas pour Google. C'est le scénario 7 (canonical absente) par défaut.
Vérifiez systématiquement le rendu Googlebot via le test d'URL enrichie de Search Console ou via Chrome DevTools en désactivant JavaScript :
# Vérifier ce que Googlebot voit sans JS rendering
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://shop.example.fr/produit/chaussure-nike-air \
| grep -i "canonical"
Si cette commande ne retourne rien, votre canonical dépend du rendering JavaScript. C'est un risque si vous êtes sur une stack API-first sans SSR.
Canonicals cross-domain
Vous pouvez déclarer une canonical vers un autre domaine (syndication de contenu, par exemple). Google respecte ce signal, mais avec plus de prudence. Le domaine cible doit être accessible, retourner un 200, et le contenu doit être suffisamment similaire. Si le domaine cible bloque Googlebot ou retourne un contenu différent, Google ignorera la canonical cross-domain.
Canonical et pages indexées via Google Discover
Pour les sites médias qui reçoivent du trafic Google Discover, la canonical est encore plus critique. Discover utilise l'URL canonique pour décider quelle version afficher dans le feed. Une canonical mal configurée peut rediriger le trafic Discover vers une URL qui n'est pas celle optimisée pour l'engagement mobile.
Checklist opérationnelle post-Mueller
Voici les vérifications à implémenter immédiatement après lecture de ces 9 scénarios :
Au niveau du template :
- Chaque page a une canonical auto-référente, sauf si elle est explicitement un doublon.
- La canonical est dans le HTML initial (pas injectée par JS uniquement).
- La canonical utilise le même protocole (HTTPS) et le même sous-domaine (www ou non) que l'URL servie.
Au niveau du serveur :
- Les redirections 301 et les canonicals pointent vers la même URL finale.
- Le header HTTP
Link: rel=canonicalest cohérent avec la balise HTML (ou absent — les deux ne sont pas nécessaires simultanément). - Les paramètres de tracking sont exclus des canonicals.
Au niveau du sitemap :
- Seules les URL canoniques sont dans le sitemap. Jamais de variantes paramétrées ou de doublons.
- Le sitemap est à jour après chaque mise à jour majeure ou refonte.
Au niveau du monitoring :
- Croisement régulier (hebdomadaire minimum) entre les canonicals déclarées et celles choisies par Google dans Search Console.
- Alertes automatiques si une canonical disparaît ou change sur plus de 1% des pages.
La canonicalisation n'est pas un sujet qu'on configure une fois et qu'on oublie. Chaque déploiement, chaque migration, chaque changement de CDN peut introduire une régression silencieuse. Les 9 scénarios de Mueller ne sont pas des cas théoriques — ce sont des bugs que Seogard détecte quotidiennement sur les sites qu'il monitore. La seule protection fiable, c'est un monitoring continu qui compare l'intention (votre canonical déclarée) avec la réalité (ce que Google a effectivement indexé).