[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f9yXbYbofcWZcvYpj7ZuY_NxqXxJ-5jYUYDxJ-ZLRyqc":3,"$fYeNHfvQ7uz5g8g-kcvRDcEkUesbIPrnO4AHtu-gt7hs":25},{"_id":4,"slug":5,"__v":6,"author":7,"body":8,"canonical":9,"category":10,"createdAt":11,"date":12,"description":13,"htmlContent":14,"image":15,"imageAlt":15,"readingTime":16,"tags":17,"title":23,"updatedAt":24},"69d1ba3ac84600c5cb80a524","google-answers-why-some-seos-split-their-sitemap-into-multiple-files-via-sejournal-martinibuster",0,"Equipe Seogard","Un site e-commerce de 28 000 URLs produit. Un seul fichier sitemap.xml de 4,2 Mo. Le crawl rate dans Search Console chute de 30% sur trois semaines sans explication apparente. Première hypothèse de l'équipe SEO : le sitemap est trop gros. Deuxième hypothèse : rien à voir. John Mueller vient de trancher cette question récurrente, et la réponse mérite qu'on s'y attarde bien au-delà du résumé en trois lignes.\n\n## Ce que John Mueller a réellement dit — et ce qu'il n'a pas dit\n\nLa déclaration de Mueller, relayée par [Search Engine Journal](https://www.searchenginejournal.com/google-answers-why-some-seos-split-their-sitemap-into-multiple-files/571097/), se résume à un point central : splitter un sitemap en plusieurs fichiers n'apporte aucun avantage direct côté crawl ou indexation pour Google. Googlebot traite un sitemap de 50 000 URLs exactement comme cinq sitemaps de 10 000 URLs, tant que les limites du protocole sont respectées.\n\nCes limites, définies par le [protocole sitemaps.org](https://www.sitemaps.org/protocol.html), sont connues :\n\n- **50 000 URLs maximum** par fichier sitemap\n- **50 Mo maximum** (non compressé) par fichier\n- Un sitemap index peut référencer jusqu'à **50 000 fichiers sitemap**\n\nMueller précise que le split est utile dans un contexte bien précis : **le debugging et le monitoring**. Quand vous segmentez vos sitemaps par type de contenu (produits, catégories, articles de blog, landing pages), vous pouvez exploiter les rapports d'indexation de Search Console par sitemap soumis. Chaque sitemap soumis individuellement dans Search Console génère ses propres statistiques d'indexation.\n\nCe que Mueller n'a pas dit, et que beaucoup d'articles omettent : cette segmentation ne change rien au comportement du crawler. Googlebot ne priorise pas un sitemap par rapport à un autre. Il ne crawle pas plus vite les URLs d'un sitemap dédié \"produits\" que celles d'un sitemap fourre-tout. La valeur est exclusivement analytique.\n\n### Le vrai bénéfice : l'observabilité\n\nSoumettre un sitemap unique contenant 28 000 URLs, c'est avoir un seul compteur d'indexation dans Search Console. Vous savez que 19 400 pages sont indexées sur 28 000 soumises. Les 8 600 manquantes ? Impossible de savoir si ce sont des fiches produit, des pages catégorie ou des articles blog sans investigation manuelle.\n\nAvec des sitemaps séparés, vous obtenez des métriques segmentées. Si votre sitemap `sitemap-products.xml` montre 12 000 URLs soumises et seulement 8 000 indexées, vous savez immédiatement que le problème d'indexation touche les fiches produit. Le diagnostic passe de quelques heures à quelques secondes.\n\n## Architecture d'un sitemap index avec segmentation par type\n\nVoici l'implémentation concrète pour un site e-commerce tournant sur Next.js avec 28 000 pages réparties en quatre types de contenu.\n\nLe fichier `sitemap.xml` à la racine devient un sitemap index :\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Csitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n  \u003Csitemap>\n    \u003Cloc>https://www.maboutique.fr/sitemaps/sitemap-products.xml\u003C/loc>\n    \u003Clastmod>2026-04-04T08:30:00+02:00\u003C/lastmod>\n  \u003C/sitemap>\n  \u003Csitemap>\n    \u003Cloc>https://www.maboutique.fr/sitemaps/sitemap-categories.xml\u003C/loc>\n    \u003Clastmod>2026-04-03T14:00:00+02:00\u003C/lastmod>\n  \u003C/sitemap>\n  \u003Csitemap>\n    \u003Cloc>https://www.maboutique.fr/sitemaps/sitemap-blog.xml\u003C/loc>\n    \u003Clastmod>2026-04-04T11:15:00+02:00\u003C/lastmod>\n  \u003C/sitemap>\n  \u003Csitemap>\n    \u003Cloc>https://www.maboutique.fr/sitemaps/sitemap-landings.xml\u003C/loc>\n    \u003Clastmod>2026-03-28T09:00:00+02:00\u003C/lastmod>\n  \u003C/sitemap>\n\u003C/sitemapindex>\n```\n\nChaque sous-sitemap contient uniquement les URLs de son type. Les `lastmod` du sitemap index reflètent la dernière modification effective d'une URL dans le sous-sitemap correspondant — pas la date de génération du fichier. Mentir sur le `lastmod` est un anti-pattern documenté par Google dans sa [documentation officielle sur les sitemaps](https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap#additional-notes-about-xml-sitemaps) : si Googlebot détecte que le `lastmod` ne correspond pas à un changement réel du contenu, il finit par ignorer ce signal.\n\n### Génération dynamique en Next.js (App Router)\n\nPour les sites utilisant Next.js 14+ avec l'App Router, la génération de sitemaps segmentés se fait via des route handlers. Voici un exemple pour le sitemap produits :\n\n```typescript\n// app/sitemaps/sitemap-products.xml/route.ts\nimport { NextResponse } from 'next/server';\nimport { getProducts } from '@/lib/db';\n\nexport async function GET() {\n  const products = await getProducts({\n    select: ['slug', 'updatedAt'],\n    where: { status: 'published' },\n    orderBy: { updatedAt: 'desc' },\n  });\n\n  const urls = products.map((product) => `\n  \u003Curl>\n    \u003Cloc>https://www.maboutique.fr/produit/${product.slug}\u003C/loc>\n    \u003Clastmod>${product.updatedAt.toISOString()}\u003C/lastmod>\n    \u003Cchangefreq>weekly\u003C/changefreq>\n    \u003Cpriority>0.8\u003C/priority>\n  \u003C/url>`).join('');\n\n  const sitemap = `\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Curlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urls}\n\u003C/urlset>`;\n\n  return new NextResponse(sitemap, {\n    headers: {\n      'Content-Type': 'application/xml',\n      'Cache-Control': 'public, max-age=3600, s-maxage=3600',\n    },\n  });\n}\n```\n\nDeux points techniques critiques ici. D'abord, le `Cache-Control` : servir un sitemap dynamique sans cache sur un site à 20 000+ produits, c'est une requête SQL lourde à chaque fetch de Googlebot. Un TTL d'une heure est un bon compromis entre fraîcheur et charge serveur. Ensuite, la requête `getProducts` ne récupère que `slug` et `updatedAt` — projeter l'ensemble des colonnes produit serait un gaspillage mémoire inutile quand vous générez un fichier qui n'a besoin que de deux champs.\n\nNote sur `changefreq` et `priority` : Google [ignore officiellement ces deux attributs](https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap#xml). Ils restent dans le protocole sitemaps.org mais n'influencent pas le comportement de Googlebot. Les inclure ne nuit pas, mais ne vous fiez pas à eux pour piloter le crawl.\n\n## Scénario concret : diagnostiquer un problème d'indexation produit\n\nPrenons un cas réaliste. Vous gérez le SEO de `maboutique.fr`, un e-commerce de mobilier avec cette répartition :\n\n- 18 500 fiches produit\n- 1 200 pages catégorie/sous-catégorie\n- 3 800 articles de blog (guides d'achat, inspirations)\n- 450 landing pages SEO (ville + type de meuble)\n\n**Avant le split** : un seul sitemap.xml de 24 000 URLs. Search Console rapporte 16 200 pages indexées. Taux d'indexation global : 67,5%. L'équipe ne sait pas quelles pages posent problème.\n\n**Après le split** : quatre sitemaps soumis séparément dans Search Console. Les résultats après 3 semaines de données :\n\n| Sitemap | Soumises | Indexées | Taux |\n|---|---|---|---|\n| sitemap-products.xml | 18 500 | 11 800 | 63,8% |\n| sitemap-categories.xml | 1 200 | 1 180 | 98,3% |\n| sitemap-blog.xml | 3 800 | 2 870 | 75,5% |\n| sitemap-landings.xml | 450 | 350 | 77,8% |\n\nLe diagnostic est immédiat : le problème d'indexation est concentré sur les fiches produit. 6 700 fiches ne sont pas indexées. L'équipe peut maintenant investiguer spécifiquement :\n\n- Fiches produit avec du contenu thin (descriptions \u003C 100 mots)\n- Produits épuisés retournant un soft 404\n- Fiches sans aucun lien interne (orphan pages)\n- Fiches avec des canonicals qui pointent vers un autre produit (variantes mal configurées)\n\nSans la segmentation, l'investigation aurait démarré par un export complet du sitemap, un croisement avec les données d'indexation via l'API Search Console ou un crawl Screaming Frog avec intégration Search Console, puis un tri manuel. Le split transforme une journée de data analysis en un constat de 30 secondes dans l'interface Search Console.\n\n### Vérification via l'API Search Console\n\nPour automatiser le suivi, vous pouvez interroger l'API Search Console pour récupérer les statistiques par sitemap soumis. Voici un script Python minimaliste :\n\n```python\nfrom google.oauth2 import service_account\nfrom googleapiclient.discovery import build\n\nSCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']\nSERVICE_ACCOUNT_FILE = 'credentials.json'\nSITE_URL = 'https://www.maboutique.fr/'\n\ncredentials = service_account.Credentials.from_service_account_file(\n    SERVICE_ACCOUNT_FILE, scopes=SCOPES\n)\nservice = build('searchconsole', 'v1', credentials=credentials)\n\n# Lister tous les sitemaps soumis\nsitemaps = service.sitemaps().list(siteUrl=SITE_URL).execute()\n\nfor sitemap in sitemaps.get('sitemap', []):\n    path = sitemap['path']\n    contents = sitemap.get('contents', [])\n    for content in contents:\n        submitted = content.get('submitted', 'N/A')\n        indexed = content.get('indexed', 'N/A')\n        print(f\"{path}: {indexed}/{submitted} indexed\")\n```\n\nCe script, exécuté en cron hebdomadaire, vous donne un tableau de bord d'indexation par type de contenu sans ouvrir Search Console. Couplé à un outil de monitoring comme Seogard, qui détecte les régressions d'indexation en temps réel, vous passez d'un monitoring passif à un système d'alerte proactif.\n\n## Les cas où le split est techniquement nécessaire (pas juste utile)\n\nMueller a insisté sur l'aspect monitoring, mais il existe des cas où le split n'est plus optionnel.\n\n### Dépassement des limites du protocole\n\nUn site média qui publie 200 articles par jour depuis 5 ans cumule potentiellement 365 000 URLs. Un seul fichier sitemap est physiquement impossible (limite de 50 000 URLs). Le sitemap index avec pagination temporelle devient obligatoire :\n\n```\nsitemap-articles-2026-q1.xml  (≈ 18 000 URLs)\nsitemap-articles-2025-q4.xml  (≈ 18 000 URLs)\nsitemap-articles-2025-q3.xml  (≈ 18 000 URLs)\n...\n```\n\nCe pattern par trimestre ou par mois a un avantage supplémentaire : les sitemaps des trimestres passés sont statiques. Ils peuvent être servis depuis un CDN avec un cache long (24h+) sans jamais être régénérés. Seul le sitemap du trimestre en cours est dynamique.\n\n### Multi-langue et hreflang\n\nPour les sites internationaux, le split par langue simplifie considérablement la gestion des `hreflang`. Un sitemap `sitemap-fr.xml` contient les URLs françaises avec leurs annotations hreflang, `sitemap-de.xml` les URLs allemandes. Quand un problème hreflang apparaît sur une langue spécifique, le diagnostic est immédiat.\n\n### Sites avec des modes de rendering mixtes\n\nC'est un cas sous-documenté mais fréquent. Un site qui utilise du [SSR pour ses pages critiques et du CSR pour d'autres](/blog/ssr-vs-csr-impact-reel-sur-le-seo) a tout intérêt à segmenter ses sitemaps en conséquence. Si les pages rendues côté client présentent des [problèmes d'indexation liés au JavaScript](/blog/pourquoi-google-voit-une-page-blanche-sur-votre-spa), un sitemap dédié permettra d'identifier immédiatement l'écart de taux d'indexation entre les deux populations de pages.\n\nDe même, les sites exploitant différents [modes de rendering (ISR, SSR, SSG)](/blog/isr-ssr-ssg-quel-mode-de-rendering-pour-le-seo) peuvent segmenter leurs sitemaps par stratégie de rendu pour monitorer l'impact de chaque approche sur l'indexation.\n\n## Les pièges de l'implémentation : ce que personne ne mentionne\n\n### Le lastmod menteur\n\nLe piège le plus fréquent : régénérer le sitemap toutes les nuits et mettre la date du jour en `lastmod` sur toutes les URLs, même celles qui n'ont pas changé. Googlebot apprend vite. Après quelques cycles de crawl où il constate que le contenu n'a pas changé malgré un `lastmod` récent, il commence à ignorer le signal sur l'ensemble de votre sitemap. Vous perdez alors la capacité de signaler les vraies mises à jour.\n\nLa bonne pratique : le `lastmod` doit refléter la dernière modification substantielle du contenu. Pas la date de build. Pas la date de dernier déploiement. La date à laquelle le contenu visible par l'utilisateur a changé.\n\n### Le sitemap orphelin\n\nVous créez quatre sitemaps segmentés, vous les soumettez dans Search Console, mais vous oubliez de mettre à jour le fichier `robots.txt`. Résultat : Googlebot découvre votre ancien `sitemap.xml` monolithique via le robots.txt et vos nouveaux sitemaps uniquement via Search Console. Vous avez maintenant des URLs déclarées en double dans deux systèmes différents.\n\nLe `robots.txt` doit pointer vers le sitemap index :\n\n```\nUser-agent: *\nDisallow: /admin/\nDisallow: /api/\n\nSitemap: https://www.maboutique.fr/sitemap-index.xml\n```\n\nEt si vous aviez un ancien `sitemap.xml`, supprimez-le ou redirigez-le en 301 vers le sitemap index. Ne laissez pas deux déclarations de sitemap coexister dans le robots.txt.\n\n### La soumission manuelle dans Search Console\n\nUn détail que beaucoup ignorent : pour bénéficier des statistiques par sitemap dans Search Console, il faut soumettre **chaque sous-sitemap individuellement**, pas seulement le sitemap index. Soumettre uniquement `sitemap-index.xml` vous donnera des statistiques agrégées. Soumettre aussi `sitemap-products.xml`, `sitemap-blog.xml`, etc. vous donnera les statistiques segmentées. Les deux approches ne sont pas mutuellement exclusives — soumettez le sitemap index ET chaque sous-sitemap.\n\n## Audit de sitemap : la checklist technique\n\nAvant de splitter, auditez l'existant. Screaming Frog permet de crawler un sitemap et de croiser les données avec la réalité du site.\n\nDans Screaming Frog :\n1. Mode > List > Download Sitemap\n2. Collez l'URL de votre sitemap\n3. Lancez le crawl\n\nVérifiez systématiquement :\n\n**URLs dans le sitemap qui retournent autre chose que 200.** Des 301, 404, 410, ou 500 dans un sitemap sont du bruit. Googlebot les crawle, constate l'erreur, et perd du temps. Sur un site de 20 000 URLs, 2 000 URLs en erreur dans le sitemap représentent 10% de crawl budget gaspillé — pas anodin quand votre [crawl budget est déjà sous pression](/blog/google-core-update-crawl-limits-gemini-traffic-data-seo-pulse-via-sejournal-mattgsouthern).\n\n**URLs dans le sitemap avec un canonical qui pointe ailleurs.** Si `/produit/chaise-bleue` est dans le sitemap mais porte un `\u003Clink rel=\"canonical\" href=\"/produit/chaise-bleu\" />`, vous envoyez un signal contradictoire à Google : \"crawle cette URL\" (sitemap) mais \"l'URL canonique est une autre\" (canonical tag). Le sitemap ne doit contenir que des URLs auto-canoniques.\n\n**URLs indexables absentes du sitemap.** L'inverse du problème précédent. Utilisez la commande de comparaison dans Screaming Frog (Crawl Analysis > Sitemap) pour identifier les pages orphelines du sitemap.\n\n**Taille du fichier non compressé.** Vérifiez avec curl :\n\n```bash\ncurl -s -o /dev/null -w '%{size_download}' https://www.maboutique.fr/sitemaps/sitemap-products.xml\n# Résultat en bytes. Divisez par 1048576 pour avoir les Mo.\n# Doit être \u003C 50 Mo non compressé.\n\n# Si vous servez en gzip, vérifiez la taille décompressée :\ncurl -s -H \"Accept-Encoding: gzip\" https://www.maboutique.fr/sitemaps/sitemap-products.xml | gunzip | wc -c\n```\n\nPour les très gros sitemaps, servir en gzip (`.xml.gz`) réduit le transfert réseau mais ne change pas la limite de 50 Mo sur le contenu décompressé. C'est le contenu XML décompressé qui est limité, pas le fichier transféré.\n\n## Faut-il splitter pour des raisons de performance de crawl ?\n\nNon. Et c'est le point central de la réponse de Mueller. Googlebot ne crawle pas un sitemap de 50 000 URLs plus lentement qu'un sitemap de 5 000 URLs de manière proportionnelle. Le parsing XML d'un fichier de quelques Mo est trivial pour l'infrastructure Google.\n\nLe crawl budget est déterminé par d'autres facteurs : la santé technique du site (temps de réponse serveur, taux d'erreurs), l'autorité perçue, la fréquence de mise à jour du contenu. La structure de vos sitemaps n'entre pas dans cette équation.\n\nEn revanche, la **performance de votre serveur** pour générer le sitemap compte. Un sitemap dynamique qui exécute une requête SQL joignant trois tables sur 50 000 lignes, sans cache, à chaque requête de Googlebot, peut poser problème. Non pas parce que Googlebot est impacté par un temps de réponse de 3 secondes sur le sitemap, mais parce que cette charge serveur dégrade le temps de réponse des pages HTML que Googlebot essaie de crawler en parallèle.\n\nLa recommandation : si votre sitemap est généré dynamiquement, mettez un cache HTTP d'au moins une heure. Si votre catalogue change peu (moins de 100 modifications par jour sur 20 000 produits), une régénération quotidienne en fichier statique est préférable.\n\n## Au-delà du split : les signaux sitemap que Google utilise vraiment\n\nPuisque `changefreq` et `priority` sont ignorés, que reste-t-il comme signal utile dans un sitemap ?\n\n**`loc`** : l'URL elle-même. Google découvre des URLs via le sitemap qu'il n'a pas encore trouvées via le crawl du linking interne. C'est le rôle principal du sitemap : un filet de sécurité pour l'exhaustivité de la découverte.\n\n**`lastmod`** : quand il est fiable, ce signal influence la fréquence de re-crawl. Google compare le `lastmod` actuel avec celui qu'il avait lors du dernier fetch. Si la date a changé, il priorise le re-crawl. D'où l'importance de ne pas mentir sur cette date.\n\n**Les URLs absentes** : retirer une URL du sitemap n'est pas un signal de désindexation (pour ça, il faut un `noindex` ou un code 410). Mais c'est un signal faible que la page est moins importante. Sur les très gros sites, des URLs présentes uniquement dans le linking interne profond ET absentes du sitemap ont statistiquement moins de chances d'être re-crawlées fréquemment.\n\nLes données remontées par Search Console dans le rapport Sitemaps sont par ailleurs à interpréter avec prudence. Google a récemment corrigé [un bug qui gonflait les compteurs d'impressions](/blog/google-is-fixing-a-search-console-bug-that-inflated-impression-counts) dans Search Console — un rappel que les données de l'interface ne sont pas toujours fiables à 100%.\n\n## Le bon réflexe : monitorer après le split\n\nSplitter son sitemap est un changement structurel. Comme toute modification technique, il faut monitorer les impacts. Vérifiez dans les semaines suivantes :\n\n- Que tous les sous-sitemaps sont bien crawlés (Search Console > Sitemaps > colonne \"Dernière lecture\")\n- Que le nombre total d'URLs soumises correspond à votre inventaire réel\n- Qu'aucun sous-sitemap ne retourne d'erreur (403, 500) intermittente\n- Que le `lastmod` du sitemap index se met à jour correctement\n\nUn outil de monitoring continu comme Seogard permet de détecter automatiquement une régression : un sous-sitemap qui retourne soudainement une 500, un `lastmod` qui cesse de se mettre à jour, ou un nombre d'URLs qui chute brutalement suite à un bug de génération. Ce type de problème silencieux peut passer inaperçu pendant des semaines dans Search Console, qui ne rafraîchit ses données qu'avec plusieurs jours de latence.\n\nLe split de sitemap n'est pas une optimisation de crawl. C'est une optimisation d'observabilité. Traitez-le comme vous traitez la segmentation de vos logs serveur ou de vos métriques applicatives : le système fonctionne pareil, mais votre capacité à diagnostiquer un problème change radicalement.","https://seogard.io/blog/google-answers-why-some-seos-split-their-sitemap-into-multiple-files-via-sejournal-martinibuster","Actualités SEO","2026-04-05T01:26:18.116Z","2026-04-05","Faut-il découper son sitemap en plusieurs fichiers ? Analyse technique des recommandations de John Mueller et implémentation concrète.","\u003Cp>Un site e-commerce de 28 000 URLs produit. Un seul fichier sitemap.xml de 4,2 Mo. Le crawl rate dans Search Console chute de 30% sur trois semaines sans explication apparente. Première hypothèse de l'équipe SEO : le sitemap est trop gros. Deuxième hypothèse : rien à voir. John Mueller vient de trancher cette question récurrente, et la réponse mérite qu'on s'y attarde bien au-delà du résumé en trois lignes.\u003C/p>\n\u003Ch2>Ce que John Mueller a réellement dit — et ce qu'il n'a pas dit\u003C/h2>\n\u003Cp>La déclaration de Mueller, relayée par \u003Ca href=\"https://www.searchenginejournal.com/google-answers-why-some-seos-split-their-sitemap-into-multiple-files/571097/\">Search Engine Journal\u003C/a>, se résume à un point central : splitter un sitemap en plusieurs fichiers n'apporte aucun avantage direct côté crawl ou indexation pour Google. Googlebot traite un sitemap de 50 000 URLs exactement comme cinq sitemaps de 10 000 URLs, tant que les limites du protocole sont respectées.\u003C/p>\n\u003Cp>Ces limites, définies par le \u003Ca href=\"https://www.sitemaps.org/protocol.html\">protocole sitemaps.org\u003C/a>, sont connues :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>50 000 URLs maximum\u003C/strong> par fichier sitemap\u003C/li>\n\u003Cli>\u003Cstrong>50 Mo maximum\u003C/strong> (non compressé) par fichier\u003C/li>\n\u003Cli>Un sitemap index peut référencer jusqu'à \u003Cstrong>50 000 fichiers sitemap\u003C/strong>\u003C/li>\n\u003C/ul>\n\u003Cp>Mueller précise que le split est utile dans un contexte bien précis : \u003Cstrong>le debugging et le monitoring\u003C/strong>. Quand vous segmentez vos sitemaps par type de contenu (produits, catégories, articles de blog, landing pages), vous pouvez exploiter les rapports d'indexation de Search Console par sitemap soumis. Chaque sitemap soumis individuellement dans Search Console génère ses propres statistiques d'indexation.\u003C/p>\n\u003Cp>Ce que Mueller n'a pas dit, et que beaucoup d'articles omettent : cette segmentation ne change rien au comportement du crawler. Googlebot ne priorise pas un sitemap par rapport à un autre. Il ne crawle pas plus vite les URLs d'un sitemap dédié \"produits\" que celles d'un sitemap fourre-tout. La valeur est exclusivement analytique.\u003C/p>\n\u003Ch3>Le vrai bénéfice : l'observabilité\u003C/h3>\n\u003Cp>Soumettre un sitemap unique contenant 28 000 URLs, c'est avoir un seul compteur d'indexation dans Search Console. Vous savez que 19 400 pages sont indexées sur 28 000 soumises. Les 8 600 manquantes ? Impossible de savoir si ce sont des fiches produit, des pages catégorie ou des articles blog sans investigation manuelle.\u003C/p>\n\u003Cp>Avec des sitemaps séparés, vous obtenez des métriques segmentées. Si votre sitemap \u003Ccode>sitemap-products.xml\u003C/code> montre 12 000 URLs soumises et seulement 8 000 indexées, vous savez immédiatement que le problème d'indexation touche les fiches produit. Le diagnostic passe de quelques heures à quelques secondes.\u003C/p>\n\u003Ch2>Architecture d'un sitemap index avec segmentation par type\u003C/h2>\n\u003Cp>Voici l'implémentation concrète pour un site e-commerce tournant sur Next.js avec 28 000 pages réparties en quatre types de contenu.\u003C/p>\n\u003Cp>Le fichier \u003Ccode>sitemap.xml\u003C/code> à la racine devient un sitemap index :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;?\u003C/span>\u003Cspan style=\"color:#85E89D\">xml\u003C/span>\u003Cspan style=\"color:#B392F0\"> version\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"1.0\"\u003C/span>\u003Cspan style=\"color:#B392F0\"> encoding\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"UTF-8\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">?>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemapindex\u003C/span>\u003Cspan style=\"color:#B392F0\"> xmlns\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"http://www.sitemaps.org/schemas/sitemap/0.9\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>https://www.maboutique.fr/sitemaps/sitemap-products.xml&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>2026-04-04T08:30:00+02:00&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>https://www.maboutique.fr/sitemaps/sitemap-categories.xml&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>2026-04-03T14:00:00+02:00&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>https://www.maboutique.fr/sitemaps/sitemap-blog.xml&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>2026-04-04T11:15:00+02:00&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>https://www.maboutique.fr/sitemaps/sitemap-landings.xml&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">loc\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    &#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>2026-03-28T09:00:00+02:00&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">lastmod\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  &#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemap\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">sitemapindex\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Chaque sous-sitemap contient uniquement les URLs de son type. Les \u003Ccode>lastmod\u003C/code> du sitemap index reflètent la dernière modification effective d'une URL dans le sous-sitemap correspondant — pas la date de génération du fichier. Mentir sur le \u003Ccode>lastmod\u003C/code> est un anti-pattern documenté par Google dans sa \u003Ca href=\"https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap#additional-notes-about-xml-sitemaps\">documentation officielle sur les sitemaps\u003C/a> : si Googlebot détecte que le \u003Ccode>lastmod\u003C/code> ne correspond pas à un changement réel du contenu, il finit par ignorer ce signal.\u003C/p>\n\u003Ch3>Génération dynamique en Next.js (App Router)\u003C/h3>\n\u003Cp>Pour les sites utilisant Next.js 14+ avec l'App Router, la génération de sitemaps segmentés se fait via des route handlers. Voici un exemple pour le sitemap produits :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// app/sitemaps/sitemap-products.xml/route.ts\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { NextResponse } \u003C/span>\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'next/server'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { getProducts } \u003C/span>\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '@/lib/db'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#F97583\"> async\u003C/span>\u003Cspan style=\"color:#F97583\"> function\u003C/span>\u003Cspan style=\"color:#B392F0\"> GET\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> products\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#B392F0\"> getProducts\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    select: [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'slug'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'updatedAt'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    where: { status: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'published'\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    orderBy: { updatedAt: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'desc'\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> urls\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> products.\u003C/span>\u003Cspan style=\"color:#B392F0\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">product\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> `\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">  &#x3C;url>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    &#x3C;loc>https://www.maboutique.fr/produit/${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">product\u003C/span>\u003Cspan style=\"color:#9ECBFF\">.\u003C/span>\u003Cspan style=\"color:#E1E4E8\">slug\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}&#x3C;/loc>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    &#x3C;lastmod>${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">product\u003C/span>\u003Cspan style=\"color:#9ECBFF\">.\u003C/span>\u003Cspan style=\"color:#E1E4E8\">updatedAt\u003C/span>\u003Cspan style=\"color:#9ECBFF\">.\u003C/span>\u003Cspan style=\"color:#B392F0\">toISOString\u003C/span>\u003Cspan style=\"color:#9ECBFF\">()\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}&#x3C;/lastmod>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    &#x3C;changefreq>weekly&#x3C;/changefreq>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    &#x3C;priority>0.8&#x3C;/priority>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">  &#x3C;/url>`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">).\u003C/span>\u003Cspan style=\"color:#B392F0\">join\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> sitemap\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> `&#x3C;?xml version=\"1.0\" encoding=\"UTF-8\"?>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">&#x3C;urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">urls\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">&#x3C;/urlset>`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  return\u003C/span>\u003Cspan style=\"color:#F97583\"> new\u003C/span>\u003Cspan style=\"color:#B392F0\"> NextResponse\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(sitemap, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'Content-Type'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'application/xml'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'Cache-Control'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'public, max-age=3600, s-maxage=3600'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Deux points techniques critiques ici. D'abord, le \u003Ccode>Cache-Control\u003C/code> : servir un sitemap dynamique sans cache sur un site à 20 000+ produits, c'est une requête SQL lourde à chaque fetch de Googlebot. Un TTL d'une heure est un bon compromis entre fraîcheur et charge serveur. Ensuite, la requête \u003Ccode>getProducts\u003C/code> ne récupère que \u003Ccode>slug\u003C/code> et \u003Ccode>updatedAt\u003C/code> — projeter l'ensemble des colonnes produit serait un gaspillage mémoire inutile quand vous générez un fichier qui n'a besoin que de deux champs.\u003C/p>\n\u003Cp>Note sur \u003Ccode>changefreq\u003C/code> et \u003Ccode>priority\u003C/code> : Google \u003Ca href=\"https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap#xml\">ignore officiellement ces deux attributs\u003C/a>. Ils restent dans le protocole sitemaps.org mais n'influencent pas le comportement de Googlebot. Les inclure ne nuit pas, mais ne vous fiez pas à eux pour piloter le crawl.\u003C/p>\n\u003Ch2>Scénario concret : diagnostiquer un problème d'indexation produit\u003C/h2>\n\u003Cp>Prenons un cas réaliste. Vous gérez le SEO de \u003Ccode>maboutique.fr\u003C/code>, un e-commerce de mobilier avec cette répartition :\u003C/p>\n\u003Cul>\n\u003Cli>18 500 fiches produit\u003C/li>\n\u003Cli>1 200 pages catégorie/sous-catégorie\u003C/li>\n\u003Cli>3 800 articles de blog (guides d'achat, inspirations)\u003C/li>\n\u003Cli>450 landing pages SEO (ville + type de meuble)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Avant le split\u003C/strong> : un seul sitemap.xml de 24 000 URLs. Search Console rapporte 16 200 pages indexées. Taux d'indexation global : 67,5%. L'équipe ne sait pas quelles pages posent problème.\u003C/p>\n\u003Cp>\u003Cstrong>Après le split\u003C/strong> : quatre sitemaps soumis séparément dans Search Console. Les résultats après 3 semaines de données :\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Sitemap\u003C/th>\n\u003Cth>Soumises\u003C/th>\n\u003Cth>Indexées\u003C/th>\n\u003Cth>Taux\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>sitemap-products.xml\u003C/td>\n\u003Ctd>18 500\u003C/td>\n\u003Ctd>11 800\u003C/td>\n\u003Ctd>63,8%\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>sitemap-categories.xml\u003C/td>\n\u003Ctd>1 200\u003C/td>\n\u003Ctd>1 180\u003C/td>\n\u003Ctd>98,3%\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>sitemap-blog.xml\u003C/td>\n\u003Ctd>3 800\u003C/td>\n\u003Ctd>2 870\u003C/td>\n\u003Ctd>75,5%\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>sitemap-landings.xml\u003C/td>\n\u003Ctd>450\u003C/td>\n\u003Ctd>350\u003C/td>\n\u003Ctd>77,8%\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Le diagnostic est immédiat : le problème d'indexation est concentré sur les fiches produit. 6 700 fiches ne sont pas indexées. L'équipe peut maintenant investiguer spécifiquement :\u003C/p>\n\u003Cul>\n\u003Cli>Fiches produit avec du contenu thin (descriptions &#x3C; 100 mots)\u003C/li>\n\u003Cli>Produits épuisés retournant un soft 404\u003C/li>\n\u003Cli>Fiches sans aucun lien interne (orphan pages)\u003C/li>\n\u003Cli>Fiches avec des canonicals qui pointent vers un autre produit (variantes mal configurées)\u003C/li>\n\u003C/ul>\n\u003Cp>Sans la segmentation, l'investigation aurait démarré par un export complet du sitemap, un croisement avec les données d'indexation via l'API Search Console ou un crawl Screaming Frog avec intégration Search Console, puis un tri manuel. Le split transforme une journée de data analysis en un constat de 30 secondes dans l'interface Search Console.\u003C/p>\n\u003Ch3>Vérification via l'API Search Console\u003C/h3>\n\u003Cp>Pour automatiser le suivi, vous pouvez interroger l'API Search Console pour récupérer les statistiques par sitemap soumis. Voici un script Python minimaliste :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> google.oauth2 \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> service_account\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> googleapiclient.discovery \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> build\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">SCOPES\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'https://www.googleapis.com/auth/webmasters.readonly'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">SERVICE_ACCOUNT_FILE\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'credentials.json'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">SITE_URL\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'https://www.maboutique.fr/'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">credentials \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> service_account.Credentials.from_service_account_file(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    SERVICE_ACCOUNT_FILE\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">scopes\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">SCOPES\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">service \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> build(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'searchconsole'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'v1'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">credentials\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">credentials)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Lister tous les sitemaps soumis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">sitemaps \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> service.sitemaps().list(\u003C/span>\u003Cspan style=\"color:#FFAB70\">siteUrl\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">SITE_URL\u003C/span>\u003Cspan style=\"color:#E1E4E8\">).execute()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> sitemap \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> sitemaps.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'sitemap'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, []):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    path \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> sitemap[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'path'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    contents \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> sitemap.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'contents'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, [])\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> content \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> contents:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        submitted \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> content.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'submitted'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'N/A'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        indexed \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> content.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'indexed'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'N/A'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        print\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#F97583\">f\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"\u003C/span>\u003Cspan style=\"color:#79B8FF\">{\u003C/span>\u003Cspan style=\"color:#E1E4E8\">path\u003C/span>\u003Cspan style=\"color:#79B8FF\">}\u003C/span>\u003Cspan style=\"color:#9ECBFF\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">{\u003C/span>\u003Cspan style=\"color:#E1E4E8\">indexed\u003C/span>\u003Cspan style=\"color:#79B8FF\">}\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#79B8FF\">{\u003C/span>\u003Cspan style=\"color:#E1E4E8\">submitted\u003C/span>\u003Cspan style=\"color:#79B8FF\">}\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> indexed\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ce script, exécuté en cron hebdomadaire, vous donne un tableau de bord d'indexation par type de contenu sans ouvrir Search Console. Couplé à un outil de monitoring comme Seogard, qui détecte les régressions d'indexation en temps réel, vous passez d'un monitoring passif à un système d'alerte proactif.\u003C/p>\n\u003Ch2>Les cas où le split est techniquement nécessaire (pas juste utile)\u003C/h2>\n\u003Cp>Mueller a insisté sur l'aspect monitoring, mais il existe des cas où le split n'est plus optionnel.\u003C/p>\n\u003Ch3>Dépassement des limites du protocole\u003C/h3>\n\u003Cp>Un site média qui publie 200 articles par jour depuis 5 ans cumule potentiellement 365 000 URLs. Un seul fichier sitemap est physiquement impossible (limite de 50 000 URLs). Le sitemap index avec pagination temporelle devient obligatoire :\u003C/p>\n\u003Cpre>\u003Ccode>sitemap-articles-2026-q1.xml  (≈ 18 000 URLs)\nsitemap-articles-2025-q4.xml  (≈ 18 000 URLs)\nsitemap-articles-2025-q3.xml  (≈ 18 000 URLs)\n...\n\u003C/code>\u003C/pre>\n\u003Cp>Ce pattern par trimestre ou par mois a un avantage supplémentaire : les sitemaps des trimestres passés sont statiques. Ils peuvent être servis depuis un CDN avec un cache long (24h+) sans jamais être régénérés. Seul le sitemap du trimestre en cours est dynamique.\u003C/p>\n\u003Ch3>Multi-langue et hreflang\u003C/h3>\n\u003Cp>Pour les sites internationaux, le split par langue simplifie considérablement la gestion des \u003Ccode>hreflang\u003C/code>. Un sitemap \u003Ccode>sitemap-fr.xml\u003C/code> contient les URLs françaises avec leurs annotations hreflang, \u003Ccode>sitemap-de.xml\u003C/code> les URLs allemandes. Quand un problème hreflang apparaît sur une langue spécifique, le diagnostic est immédiat.\u003C/p>\n\u003Ch3>Sites avec des modes de rendering mixtes\u003C/h3>\n\u003Cp>C'est un cas sous-documenté mais fréquent. Un site qui utilise du \u003Ca href=\"/blog/ssr-vs-csr-impact-reel-sur-le-seo\">SSR pour ses pages critiques et du CSR pour d'autres\u003C/a> a tout intérêt à segmenter ses sitemaps en conséquence. Si les pages rendues côté client présentent des \u003Ca href=\"/blog/pourquoi-google-voit-une-page-blanche-sur-votre-spa\">problèmes d'indexation liés au JavaScript\u003C/a>, un sitemap dédié permettra d'identifier immédiatement l'écart de taux d'indexation entre les deux populations de pages.\u003C/p>\n\u003Cp>De même, les sites exploitant différents \u003Ca href=\"/blog/isr-ssr-ssg-quel-mode-de-rendering-pour-le-seo\">modes de rendering (ISR, SSR, SSG)\u003C/a> peuvent segmenter leurs sitemaps par stratégie de rendu pour monitorer l'impact de chaque approche sur l'indexation.\u003C/p>\n\u003Ch2>Les pièges de l'implémentation : ce que personne ne mentionne\u003C/h2>\n\u003Ch3>Le lastmod menteur\u003C/h3>\n\u003Cp>Le piège le plus fréquent : régénérer le sitemap toutes les nuits et mettre la date du jour en \u003Ccode>lastmod\u003C/code> sur toutes les URLs, même celles qui n'ont pas changé. Googlebot apprend vite. Après quelques cycles de crawl où il constate que le contenu n'a pas changé malgré un \u003Ccode>lastmod\u003C/code> récent, il commence à ignorer le signal sur l'ensemble de votre sitemap. Vous perdez alors la capacité de signaler les vraies mises à jour.\u003C/p>\n\u003Cp>La bonne pratique : le \u003Ccode>lastmod\u003C/code> doit refléter la dernière modification substantielle du contenu. Pas la date de build. Pas la date de dernier déploiement. La date à laquelle le contenu visible par l'utilisateur a changé.\u003C/p>\n\u003Ch3>Le sitemap orphelin\u003C/h3>\n\u003Cp>Vous créez quatre sitemaps segmentés, vous les soumettez dans Search Console, mais vous oubliez de mettre à jour le fichier \u003Ccode>robots.txt\u003C/code>. Résultat : Googlebot découvre votre ancien \u003Ccode>sitemap.xml\u003C/code> monolithique via le robots.txt et vos nouveaux sitemaps uniquement via Search Console. Vous avez maintenant des URLs déclarées en double dans deux systèmes différents.\u003C/p>\n\u003Cp>Le \u003Ccode>robots.txt\u003C/code> doit pointer vers le sitemap index :\u003C/p>\n\u003Cpre>\u003Ccode>User-agent: *\nDisallow: /admin/\nDisallow: /api/\n\nSitemap: https://www.maboutique.fr/sitemap-index.xml\n\u003C/code>\u003C/pre>\n\u003Cp>Et si vous aviez un ancien \u003Ccode>sitemap.xml\u003C/code>, supprimez-le ou redirigez-le en 301 vers le sitemap index. Ne laissez pas deux déclarations de sitemap coexister dans le robots.txt.\u003C/p>\n\u003Ch3>La soumission manuelle dans Search Console\u003C/h3>\n\u003Cp>Un détail que beaucoup ignorent : pour bénéficier des statistiques par sitemap dans Search Console, il faut soumettre \u003Cstrong>chaque sous-sitemap individuellement\u003C/strong>, pas seulement le sitemap index. Soumettre uniquement \u003Ccode>sitemap-index.xml\u003C/code> vous donnera des statistiques agrégées. Soumettre aussi \u003Ccode>sitemap-products.xml\u003C/code>, \u003Ccode>sitemap-blog.xml\u003C/code>, etc. vous donnera les statistiques segmentées. Les deux approches ne sont pas mutuellement exclusives — soumettez le sitemap index ET chaque sous-sitemap.\u003C/p>\n\u003Ch2>Audit de sitemap : la checklist technique\u003C/h2>\n\u003Cp>Avant de splitter, auditez l'existant. Screaming Frog permet de crawler un sitemap et de croiser les données avec la réalité du site.\u003C/p>\n\u003Cp>Dans Screaming Frog :\u003C/p>\n\u003Col>\n\u003Cli>Mode > List > Download Sitemap\u003C/li>\n\u003Cli>Collez l'URL de votre sitemap\u003C/li>\n\u003Cli>Lancez le crawl\u003C/li>\n\u003C/ol>\n\u003Cp>Vérifiez systématiquement :\u003C/p>\n\u003Cp>\u003Cstrong>URLs dans le sitemap qui retournent autre chose que 200.\u003C/strong> Des 301, 404, 410, ou 500 dans un sitemap sont du bruit. Googlebot les crawle, constate l'erreur, et perd du temps. Sur un site de 20 000 URLs, 2 000 URLs en erreur dans le sitemap représentent 10% de crawl budget gaspillé — pas anodin quand votre \u003Ca href=\"/blog/google-core-update-crawl-limits-gemini-traffic-data-seo-pulse-via-sejournal-mattgsouthern\">crawl budget est déjà sous pression\u003C/a>.\u003C/p>\n\u003Cp>\u003Cstrong>URLs dans le sitemap avec un canonical qui pointe ailleurs.\u003C/strong> Si \u003Ccode>/produit/chaise-bleue\u003C/code> est dans le sitemap mais porte un \u003Ccode>&#x3C;link rel=\"canonical\" href=\"/produit/chaise-bleu\" />\u003C/code>, vous envoyez un signal contradictoire à Google : \"crawle cette URL\" (sitemap) mais \"l'URL canonique est une autre\" (canonical tag). Le sitemap ne doit contenir que des URLs auto-canoniques.\u003C/p>\n\u003Cp>\u003Cstrong>URLs indexables absentes du sitemap.\u003C/strong> L'inverse du problème précédent. Utilisez la commande de comparaison dans Screaming Frog (Crawl Analysis > Sitemap) pour identifier les pages orphelines du sitemap.\u003C/p>\n\u003Cp>\u003Cstrong>Taille du fichier non compressé.\u003C/strong> Vérifiez avec curl :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -o\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> /dev/null\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -w\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '%{size_download}'\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://www.maboutique.fr/sitemaps/sitemap-products.xml\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Résultat en bytes. Divisez par 1048576 pour avoir les Mo.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Doit être &#x3C; 50 Mo non compressé.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Si vous servez en gzip, vérifiez la taille décompressée :\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -H\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"Accept-Encoding: gzip\"\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://www.maboutique.fr/sitemaps/sitemap-products.xml\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> gunzip\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> wc\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -c\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Pour les très gros sitemaps, servir en gzip (\u003Ccode>.xml.gz\u003C/code>) réduit le transfert réseau mais ne change pas la limite de 50 Mo sur le contenu décompressé. C'est le contenu XML décompressé qui est limité, pas le fichier transféré.\u003C/p>\n\u003Ch2>Faut-il splitter pour des raisons de performance de crawl ?\u003C/h2>\n\u003Cp>Non. Et c'est le point central de la réponse de Mueller. Googlebot ne crawle pas un sitemap de 50 000 URLs plus lentement qu'un sitemap de 5 000 URLs de manière proportionnelle. Le parsing XML d'un fichier de quelques Mo est trivial pour l'infrastructure Google.\u003C/p>\n\u003Cp>Le crawl budget est déterminé par d'autres facteurs : la santé technique du site (temps de réponse serveur, taux d'erreurs), l'autorité perçue, la fréquence de mise à jour du contenu. La structure de vos sitemaps n'entre pas dans cette équation.\u003C/p>\n\u003Cp>En revanche, la \u003Cstrong>performance de votre serveur\u003C/strong> pour générer le sitemap compte. Un sitemap dynamique qui exécute une requête SQL joignant trois tables sur 50 000 lignes, sans cache, à chaque requête de Googlebot, peut poser problème. Non pas parce que Googlebot est impacté par un temps de réponse de 3 secondes sur le sitemap, mais parce que cette charge serveur dégrade le temps de réponse des pages HTML que Googlebot essaie de crawler en parallèle.\u003C/p>\n\u003Cp>La recommandation : si votre sitemap est généré dynamiquement, mettez un cache HTTP d'au moins une heure. Si votre catalogue change peu (moins de 100 modifications par jour sur 20 000 produits), une régénération quotidienne en fichier statique est préférable.\u003C/p>\n\u003Ch2>Au-delà du split : les signaux sitemap que Google utilise vraiment\u003C/h2>\n\u003Cp>Puisque \u003Ccode>changefreq\u003C/code> et \u003Ccode>priority\u003C/code> sont ignorés, que reste-t-il comme signal utile dans un sitemap ?\u003C/p>\n\u003Cp>\u003Cstrong>\u003Ccode>loc\u003C/code>\u003C/strong> : l'URL elle-même. Google découvre des URLs via le sitemap qu'il n'a pas encore trouvées via le crawl du linking interne. C'est le rôle principal du sitemap : un filet de sécurité pour l'exhaustivité de la découverte.\u003C/p>\n\u003Cp>\u003Cstrong>\u003Ccode>lastmod\u003C/code>\u003C/strong> : quand il est fiable, ce signal influence la fréquence de re-crawl. Google compare le \u003Ccode>lastmod\u003C/code> actuel avec celui qu'il avait lors du dernier fetch. Si la date a changé, il priorise le re-crawl. D'où l'importance de ne pas mentir sur cette date.\u003C/p>\n\u003Cp>\u003Cstrong>Les URLs absentes\u003C/strong> : retirer une URL du sitemap n'est pas un signal de désindexation (pour ça, il faut un \u003Ccode>noindex\u003C/code> ou un code 410). Mais c'est un signal faible que la page est moins importante. Sur les très gros sites, des URLs présentes uniquement dans le linking interne profond ET absentes du sitemap ont statistiquement moins de chances d'être re-crawlées fréquemment.\u003C/p>\n\u003Cp>Les données remontées par Search Console dans le rapport Sitemaps sont par ailleurs à interpréter avec prudence. Google a récemment corrigé \u003Ca href=\"/blog/google-is-fixing-a-search-console-bug-that-inflated-impression-counts\">un bug qui gonflait les compteurs d'impressions\u003C/a> dans Search Console — un rappel que les données de l'interface ne sont pas toujours fiables à 100%.\u003C/p>\n\u003Ch2>Le bon réflexe : monitorer après le split\u003C/h2>\n\u003Cp>Splitter son sitemap est un changement structurel. Comme toute modification technique, il faut monitorer les impacts. Vérifiez dans les semaines suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>Que tous les sous-sitemaps sont bien crawlés (Search Console > Sitemaps > colonne \"Dernière lecture\")\u003C/li>\n\u003Cli>Que le nombre total d'URLs soumises correspond à votre inventaire réel\u003C/li>\n\u003Cli>Qu'aucun sous-sitemap ne retourne d'erreur (403, 500) intermittente\u003C/li>\n\u003Cli>Que le \u003Ccode>lastmod\u003C/code> du sitemap index se met à jour correctement\u003C/li>\n\u003C/ul>\n\u003Cp>Un outil de monitoring continu comme Seogard permet de détecter automatiquement une régression : un sous-sitemap qui retourne soudainement une 500, un \u003Ccode>lastmod\u003C/code> qui cesse de se mettre à jour, ou un nombre d'URLs qui chute brutalement suite à un bug de génération. Ce type de problème silencieux peut passer inaperçu pendant des semaines dans Search Console, qui ne rafraîchit ses données qu'avec plusieurs jours de latence.\u003C/p>\n\u003Cp>Le split de sitemap n'est pas une optimisation de crawl. C'est une optimisation d'observabilité. Traitez-le comme vous traitez la segmentation de vos logs serveur ou de vos métriques applicatives : le système fonctionne pareil, mais votre capacité à diagnostiquer un problème change radicalement.\u003C/p>",null,12,[18,19,20,21,22],"sitemap","crawl budget","google","seo technique","indexation","Splitter son sitemap XML : ce que Google recommande vraiment","Sun Apr 05 2026 01:41:23 GMT+0000 (Coordinated Universal Time)",[26,41,54],{"_id":27,"slug":28,"__v":6,"author":7,"canonical":29,"category":10,"createdAt":30,"date":31,"description":32,"image":15,"imageAlt":15,"readingTime":16,"tags":33,"title":39,"updatedAt":40},"69d724dbaa6b273b0cf88f96","how-ai-search-defines-market-relevance-beyond-hreflang","https://seogard.io/blog/how-ai-search-defines-market-relevance-beyond-hreflang","2026-04-09T04:02:35.927Z","2026-04-09","Hreflang ne suffit plus. Découvrez les signaux que l'IA utilise pour sélectionner vos pages locales dans les réponses générées par marché.",[34,35,36,37,38],"search","market relevance","hreflang","AI search","international SEO","AI Search : comment la pertinence locale se joue au-delà de hreflang","Thu Apr 09 2026 04:02:35 GMT+0000 (Coordinated Universal Time)",{"_id":42,"slug":43,"__v":6,"author":7,"canonical":44,"category":10,"createdAt":45,"date":31,"description":46,"image":15,"imageAlt":15,"readingTime":16,"tags":47,"title":52,"updatedAt":53},"69d75d2baa6b273b0c25874d","google-confirms-march-2026-core-update-is-complete-via-sejournal-mattgsouthern","https://seogard.io/blog/google-confirms-march-2026-core-update-is-complete-via-sejournal-mattgsouthern","2026-04-09T08:02:51.680Z","Le core update de mars 2026 est terminé. Méthodologie d'analyse, signaux à surveiller, requêtes GSC et scénarios concrets pour mesurer l'impact réel.",[20,48,49,50,51],"core update","march 2026","search console","analyse SEO","March 2026 Core Update : analyse technique post-rollout","Thu Apr 09 2026 08:02:51 GMT+0000 (Coordinated Universal Time)",{"_id":55,"slug":56,"__v":6,"author":7,"canonical":57,"category":10,"createdAt":58,"date":59,"description":60,"image":15,"imageAlt":15,"readingTime":16,"tags":61,"title":66,"updatedAt":67},"69d5d358fd4d84bed98d86ff","google-ai-overviews-90-accurate-yet-millions-of-errors-remain-analysis","https://seogard.io/blog/google-ai-overviews-90-accurate-yet-millions-of-errors-remain-analysis","2026-04-08T04:02:32.018Z","2026-04-08","Analyse technique de la fiabilité des AI Overviews Google : impact SEO, détection des réponses fausses, et stratégies pour protéger votre trafic organique.",[20,62,63,64,65,21],"ai overviews","accurate","millions","errors","AI Overviews : 90% de précision, des millions d'erreurs/jour","Wed Apr 08 2026 04:02:32 GMT+0000 (Coordinated Universal Time)"]