Il y a trois ans, j'ai pris un blog client -- 400 articles, 60k visites organiques mensuelles, huit ans de PageRank accumulé -- et l'ai migré vers une interface Next.js flambant neuve. En six semaines, nous avions perdu 34% de ce trafic. Pas parce que le nouveau site était lent. Pas parce que le contenu avait disparu. Parce que j'ai été négligent sur quatre points spécifiques que je vais vous expliquer dans cet article pour que vous ne répétiez pas mon erreur.
WordPress headless avec Next.js est vraiment brillant pour la performance et l'expérience développeur. Mais Google s'en fiche de votre score Lighthouse si vos balises canonical sont mal configurées, votre sitemap XML pointe vers l'ancien domaine, et vos données structurées ont disparu quelque part entre WPGraphQL et getStaticProps. La migration elle-même, c'est la partie dangereuse. Bien la réussir, c'est surtout une question de discipline, pas de magie.getStaticProps. The migration itself is the dangerous part. Getting it right is mostly about discipline, not magic.
---
Pourquoi Cette Migration Casse le SEO en Première Lieu
Voilà ce que la plupart des tutoriels passent sous silence : WordPress fait un énorme travail SEO pour vous sans que vous le réalisiez. Yoast ou Rank Math génère vos balises meta. Le cœur de WordPress gère votre structure de permaliens. Votre thème sort probablement une forme de balisage schema. Votre sitemap XML se régénère automatiquement à chaque publication.some kind of schema markup. Your XML sitemap auto-regenerates every time you publish.
Quand vous tirez la couche contenu dans Next.js via l'API WPGraphQL et que vous la servez depuis un nouveau front-end, toute cette infrastructure devient votre problème à reproduire. Chaque. Seul. Élément.WPGraphQL API and serve it from a new front-end, all of that infrastructure becomes your problem to replicate. Every. Single. Piece.
L'autre problème est la structure des URLs. La plupart des sites WordPress ont /category/post-slug/ ou /year/month/post-slug/ ou simplement /post-slug/. Next.js vous offre une toile vierge pour le routage. Cette toile vierge est un cimetière de classements si vous ne la planifiez pas soigneusement./category/post-slug/or/year/month/post-slug/or just/post-slug/. Next.js gives you a blank canvas for routing. That blank canvas is a ranking graveyard if you don't plan it carefully.
Les Deux Modes de Défaillance que Je Vois Constamment
Le premier concerne les équipes qui migrent aussi les URLs et cassent quand même les choses -- généralement parce que les redirections sont appliquées de façon incohérente ou que le nouveau sitemap est mis en ligne avant les redirections. Le second concerne les équipes qui changent intentionnellement la structure des URL (souvent pour la nettoyer) et traitent le mappage des redirections comme une pensée secondaire. Les deux sont corrigeables. Aucun des deux n'est acceptable.
---
Auditez Avant de Toucher à Quoi que Ce Soit
N'écrivez pas une seule ligne de code Next.js avant d'avoir un inventaire complet des URL. J'utilise Screaming Frog -- crawlez le site WordPress en direct, exportez toutes les URL indexables, et versez-les dans un tableur. Pour un site de 400 pages c'est peut-être une heure de travail. Pour un site de 4 000 pages c'est toujours juste une heure, parce que l'outil le fait automatiquement.Screaming Frog -- crawl the live WordPress site, export every indexable URL, and dump it into a spreadsheet. For a 400-page site that's maybe an hour of work. For a 4,000-page site it's still just an hour, because the tool does it automatically.
Ce que vous capturez :
- Chaque URL canonique actuellement indexée
- Le statut HTTP de chacune (identifier les 404s et les 301s qui existent déjà)
- Le titre meta et la description pour chaque page
- Quelles pages ont des données structurées (utilisez le Rich Results Test ou inspectez simplement la source)
- Les liens internes entrants -- pour savoir quelles pages renvoient vers quelles pages
Récupérez également vos 50 meilleures pages de Google Search Console triées par clics. Ce sont celles que vous ne pouvez pas vous permettre de rater. Signalez-les dans la feuille de calcul. Traitez-les comme des dépendances en production.
Seahawk avait un client e-commerce fin 2022 -- un magasin WooCommerce de 1 200 produits migrant vers une configuration headless. Nous avons passé deux jours complets sur l'audit avant d'écrire du code. Le client pensait que nous gaspillions du temps. Nous avons sauvé ses 90k sessions organiques mensuelles.
---
Configurer WordPress en tant que véritable CMS Headless
Cette partie est surtout directe. Installez WPGraphQL et exposez votre contenu via l'API GraphQL. Mais il y a quelques points sur lesquels il vaut la peine d'être délibéré.
Gardez Yoast (ou Rank Math) en fonction du côté WordPress
Même si vous ne servez plus WordPress comme interface publique, gardez votre plugin SEO actif. WPGraphQL for Yoast SEO (ou l'extension Rank Math équivalente) expose toutes les métadonnées SEO -- titres, descriptions, URLs canoniques, données OG, directives robots -- directement via l'API GraphQL. Cela signifie que vous pouvez l'interroger depuis Next.js et le rendre exactement comme Yoast l'a prévu.WPGraphQL for Yoast SEO(or the equivalent Rank Math extension) exposes all the SEO meta -- titles, descriptions, canonical URLs, OG data, robots directives -- directly through the GraphQL API. That means you can query it from Next.js and render it exactly as Yoast intended.
C'était la leçon de cette baisse de trafic en 2019 que j'ai mentionnée. J'avais supposé que nous pourrions régénérer les titres à partir du titre du post + le nom du site dans Next.js. Nous pourrions. Mais Yoast avait personnalisé manuellement les meta titres pour environ 80 des posts les plus performants, et nous avons tout effacé. Huit semaines pour récupérer.
Désactiver le Front-End WordPress avec Prudence
Une fois que vous êtes prêt à diriger le trafic vers Next.js, vous ne voulez PAS que WordPress serve son propre front-end en même temps. Contenu en double à grande échelle. La façon la plus propre est de définir un robots.txt sur votre installation WordPress à Disallow: / pendant que votre site Next.js se met en ligne, puis finalement de firewall l'URL WordPress pour qu'elle ne soit accessible qu'en interne ou via VPN.robots.txt on your WordPress install to Disallow: /while your Next.js site goes live, then eventually firewall the WordPress URL entirely so it's only accessible internally or via VPN.
Ne sauter pas l'étape robots.txt. J'ai vu des équipes bloquer WordPress au niveau du CDN et découvrir ensuite que Googlebot avait une route en cache. Cela prend des mois pour nettoyer.
---
Reproduire la Structure d'URL Exactement
Ma forte recommandation par défaut : conservez vos URLs identiques. Même slug, même structure de permalink, même comportement de trailing slash. Plus les routes Next.js reflètent les routes WordPress, moins vous avez besoin de redirects, et moins vous prenez de risques.keep your URLs identical. Same slug, same permalink structure, same trailing slash behaviour. The closer the Next.js routes mirror the WordPress routes, the fewer redirects you need, and the less risk you carry.
Les routes dynamiques de Next.js rendent cela facile. Si vos articles WordPress vivent à /blog/[slug], créez pages/blog/[slug].js. C'est bon.dynamic routes make this easy. If your WordPress posts live at/blog/[slug], create pages/blog/[slug].js. Done.
Ça devient compliqué avec les archives de catégories, les pages d'auteur, les pages de tags, et les archives paginées (/blog/page/2/). WordPress génère tout cela automatiquement. Dans Next.js vous les construisez vous-même. Beaucoup d'équipes déprioritisent ces éléments et se demandent ensuite pourquoi la couverture de crawl a chuté./blog/page/2/). WordPress generates all of these automatically. In Next.js you're building them yourself. A lot of teams deprioritise these and then wonder why crawl coverage dropped.
Voici ma checklist numérotée pour la parité d'URL :
- Articles/pages individuels -- faire correspondre le slug exactement, y compris tout sous-dossier -- match the slug exactly, including any subfolder
- Archives de catégories -- recréer /category/[slug]/ avec getStaticPaths tirant toutes les catégories de WPGraphQL -- recreate
/category/[slug]/withgetStaticPathspulling all categories from WPGraphQL - Archives de tags -- idem que ci-dessus, ne les supprimez pas s'ils reçoivent du trafic organique -- same as above, don't skip these if they get organic traffic
- Archives d'auteurs -- vérifiez d'abord Search Console ; s'ils n'ont zéro clics, vous pouvez les rediriger en 301 vers la page d'accueil -- check Search Console first; if they get zero clicks, you can 301 them to the homepage
- Archives paginées -- /blog/page/[num]/ vaut la peine d'être conservée si vous avez beaucoup d'articles --
/blog/page/[num]/is worth preserving if you have a lot of posts - Pages de pièces jointes -- presque toujours les rediriger en 301 vers l'article parent ; ce sont des poids morts pour le SEO dans WordPress aussi -- almost always 301 these to the parent post; they're SEO dead weight in WordPress too
- URLs de flux -- /feed/ doit se rediriger en 301 vers votre nouveau flux RSS si vous en avez un, ou retourner 410 si ce n'est pas le cas --
/feed/should 301 to your new RSS feed if you have one, or return 410 if not
---
Redirections : la partie que tout le monde sous-estime
Si vous modifiez des URLs -- ce que je vous déconseille, mais parfois c'est nécessaire -- votre table de redirection doit être construite avant le lancement et testée dans un environnement de staging.are changing any URLs -- which I'd push back on, but sometimes it's necessary -- your redirect map needs to be built before launch and tested in a staging environment.
Dans Next.js, les redirections se trouvent dans next.config.js. Pour les petits sites (moins de 200 redirections), c'est correct. Pour les plus grands, mettez-les dans un fichier JSON et importez-le, ou utilisez un middleware pour les gérer dynamiquement. Le middleware edge de Vercel est excellent pour les grandes tables de redirection parce qu'il s'exécute avant le rendu de la page -- aucune pénalité de latence.next.config.js. For small sites (under 200 redirects) that's fine. For anything larger, put them in a JSON file and import it, or use middleware to handle them dynamically.Vercel's edge middleware is excellent for large redirect tables because it runs before the page is rendered -- zero latency penalty.
Le format dans next.config.js :next.config.js:
``redirects: [ { source: '/old-slug', destination: '/new-slug', permanent: true } ]``redirects: [ { source: '/old-slug', destination: '/new-slug', permanent: true } ]``
permanent: true envoie un 301. Utilisez-le pour tous les changements d'URL authentiques. N'utilisez pas 302 (temporaire) à moins que vous ayez vraiment l'intention de le revenir -- Google les traite très différemment. sends a 301. Use it for all genuine URL changes. Don't use 302 (temporary) unless you actually intend to revert it -- Google treats them very differently.
Testez chaque redirect avant le lancement. J'utilise un simple script bash qui boucle dans la feuille de calcul et curl chaque ancienne URL en vérifiant une réponse 301 vers la bonne destination. Ça prend dix minutes à écrire, ça vous épargne des heures de panique post-lancement.
---
Meta Tags, Canonical URLs, et Structured Data dans Next.js
C'est là que la plupart des migrations perdent des points silencieusement. Le contenu est là, les URLs fonctionnent, mais les signaux SEO sont faux.
Meta Tags
Utilisez next-seo. C'est le standard. Transmettez-lui les données que vous avez interrogées depuis WPGraphQL Yoast. Votre _app.js obtient une configuration DefaultSeo, et chaque page obtient un composant NextSeo avec les surcharges spécifiques à la page. Prenez le titre, la description, le titre OG, l'image OG, l'URL canonique et les directives robots directement de la réponse GraphQL Yoast -- ne les réinventez pas.next-seo. It's the standard. Pass it the data you've queried from WPGraphQL Yoast. Your_app.js gets a DefaultSeo config, and each page gets a NextSeo component with the page-specific overrides. Take the title, description, OG title, OG image, canonical URL, and robots directives directly from the Yoast GraphQL response -- don't reinvent them.
Un truc qui pose problème : les URLs canoniques. Dans WordPress, Yoast les définit automatiquement. Dans Next.js, vous devez passer la canonique explicitement. Si vous l'oubliez, Next.js affichera les pages sans balise canonique, et si vous avez des query strings quelque part (pagination, filtres), vous vous retrouverez avec des problèmes de contenu dupliqué plus vite que prévu.
Données structurées
Les thèmes et plugins WordPress produisent souvent du JSON-LD automatiquement. Cela disparaît en headless. Vous devez le reconstruire. Pour les articles, utilisez le schéma Article. Pour les produits, Product. Pour les entreprises locales, LocalBusiness. Je les écris comme des composants React qui acceptent des props et retournent une balise <script type="application/ld+json">. Un composant par type de schéma, réutilisé dans toute l'application.Article schema. For products,Product. For local businesses,LocalBusiness. I write these as React components that accept props and return a<script type="application/ld+json">tag. One component per schema type, reused across the app.
Vérifiez chaque type de schéma que vous aviez auparavant dans le Rich Results Test avant la migration. Documentez-les. Recréez-les. Testez les nouveaux avec le même outil après le lancement.before migration. Document them. Recreate them. Test the new ones with the same tool post-launch.
Le sitemap XML
N'utilisez pas un sitemap statique. Générez-le dynamiquement. Pour les petits sites, getServerSideProps sur une route /sitemap.xml fonctionne. Pour les grands sites avec des milliers d'articles, générez le sitemap au moment de la compilation via un script personnalisé et exportez-le vers le dossier public/. Vercel l'exécute à chaque déploiement -- votre sitemap est toujours à jour.getServerSideProps on a/sitemap.xml route works. For large sites with thousands of posts, generate the sitemap at build time via a custom script and output it to the public/folder. Vercel runs this at every deployment -- your sitemap is always current.
Soumettez la nouvelle URL du sitemap à Google Search Console le premier jour du lancement du nouveau site. Pas le troisième jour. Le premier jour.
---
Suivi post-lancement (La fenêtre de 90 jours)
La migration ne s'arrête pas au lancement. Elle s'arrête quand vos classements se sont stabilisés -- ce que la documentation de Google suggère peut prendre de quelques semaines à quelques mois selon votre budget de crawl et l'autorité de votre site.
Ce que je consulte chaque jour de la semaine pendant le premier mois :
- Google Search Console → Rapport de couverture pour les nouveaux 404 ou les URL « Exclues » qui ne devraient pas l'être for new 404s or 'Excluded' URLs that shouldn't be excluded
- Search Console → Performance -- comparez les clics et les impressions semaine après semaine pour vos 50 meilleures pages -- compare clicks and impressions week-on-week for your top 50 pages
- Re-crawl de Screaming Frog du nouveau site pour détecter les 404 internes ou les balises canoniques mal configurées of the new site to catch any internal 404s or misconfigured canonical tags
- Core Web Vitals -- oui, le site Next.js devrait être plus rapide, mais vérifiez-le dans les données du terrain (CrUX), pas seulement dans Lighthouse -- yes, the Next.js site should be faster, but verify it in the field data (CrUX), not just Lighthouse
Si vous constatez une baisse significative lors des deux ou trois premières semaines, ne paniquez pas immédiatement. Il y a presque toujours une courte fluctuation tandis que Google effectue le re-crawl et la ré-indexation. Ce que vous recherchez, c'est une baisse soutenue au-delà de la semaine quatre. C'est le signal qu'il y a un problème structurel.
Fin 2022 -- projet différent de celui de l'e-commerce -- nous avons lancé une migration Next.js pour un blog SaaS et avons vu une baisse de 20% des impressions à la deuxième semaine. Il s'avère que notre sitemap générée dynamiquement incluait des pages noindex parce que nous n'avions pas filtré correctement la requête WPGraphQL. Nous l'avons corrigé en quatre heures. Les classements se sont rétablis en trois semaines. La surveillance l'a détecté avant que ça s'aggrave.noindex pages because we hadn't filtered the WPGraphQL query properly. Fixed it in four hours. Rankings recovered in three weeks. The monitoring caught it before it compounded.
---
FAQ
Combien de temps prend une migration WordPress vers Next.js ?
Honnêtement, ça dépend surtout de la complexité du site, pas du nombre de posts. Un site brochure de 100 pages avec des URLs propres peut être fait correctement en deux à trois semaines. Un blog de 2 000 posts avec des custom post types, des champs ACF et une intégration WooCommerce, c'est un projet de six à huit semaines minimum si tu fais le travail SEO correctement en parallèle du développement. Ne laisse personne te dire que c'est un boulot de week-end.
Dois-je utiliser le Pages Router ou l'App Router dans Next.js ?
Depuis mi-2024, je fais défaut à l'App Router pour les nouveaux projets. Mais si votre équipe est plus à l'aise avec le Pages Router et qu'il s'agit d'une migration urgente, utilisez ce que vous connaissez. Les implications SEO sont minimes -- les deux supportent la génération statique, le rendu côté serveur et les routes dynamiques. Le package next-seo a maintenant le support de l'App Router aussi.next-seo package has App Router support now too.
Dois-je entièrement m'éloigner de l'hébergement WordPress ?
Non. WordPress peut rester sur son hôte existant -- WP Engine, Kinsta, Cloudways, peu importe ce que vous utilisez -- et agir purement comme une API de contenu. Le front-end Next.js se déploie sur Vercel ou Netlify. Les deux communiquent via HTTP. Certains clients préfèrent d'ailleurs ça parce que l'équipe éditoriale garde l'admin WordPress qu'elle connaît déjà.Netlify. The two communicate via HTTP. Some clients actually prefer this because the editorial team keeps the WordPress admin they already know.
Et les extensions WordPress qui affectent le SEO -- comme les redirections gérées dans Redirection ?
Exportez-les avant de migrer. L'extension Redirection a une export CSV. Prenez toutes ces redirections existantes et ajoutez-les à votre next.config.js ou middleware edge. Ne supposez pas qu'elles vont se transférer automatiquement -- elles ne le feront pas, parce qu'elles vivent dans la base de données WordPress et Next.js ne sait pas qu'elles existent.Redirection plugin has a CSV export. Take all those existing redirects and add them to your next.config.js or edge middleware. Don't assume they'll carry over automatically -- they won't, because they live in the WordPress database and Next.js has no idea they exist.
Mon classement Google va-t-il baisser peu importe quoi ?
Il y a presque toujours une certaine volatilité à court terme. Une migration bien exécutée sans changement d'URL, avec les bonnes redirections (quand nécessaire), avec les méta et les données structurées répliquées, et un sitemap résoumis devrait se stabiliser en quatre à six semaines. Les baisses que j'ai vues qui ont duré des mois ont toutes été causées par des erreurs techniques spécifiques -- pas par la migration elle-même.
---
La migration n'est pas la partie difficile. La partie difficile, c'est la discipline de faire chaque étape ennuyeuse et sans éclat -- l'audit, le mappage des redirections, la récréation du schéma -- avant d'écrire du code Next.js astucieux. Si vous faites ça dans le bon ordre, vous allez en sortir avec un front-end plus rapide et les mêmes classements avec lesquels vous avez commencé. Possiblement de meilleurs, une fois que les améliorations de Core Web Vitals se répercutent.Core Web Vitals improvements feed through.
