wordpress-to-nextjs-migration-seo.html
< BACK Catálogo de fichas vintage em uma sala de arquivo escura com luz âmbar quente e cartões de índice espalhados

Migrar WordPress para Next.js Sem Perder SEO

Há três anos peguei o blog de um cliente -- 400 posts, 60 mil visitas orgânicas mensais, oito anos de PageRank acumulado -- e migrei para um front-end Next.js brilhante. Em seis semanas perdemos 34% daquele tráfego. Não porque o novo site era lento. Não porque o conteúdo desapareceu. Porque fui negligente com quatro coisas específicas que vou detalhar neste post para você não repetir meu erro.

WordPress headless com Next.js é genuinamente brilhante para performance e experiência do desenvolvedor. Mas Google não se importa com seu score do Lighthouse se suas canonical tags estão erradas, seu XML sitemap aponta para o domínio antigo, e seus structured data desapareceram em algum lugar entre WPGraphQL e getStaticProps. A migração em si é a parte perigosa. Acertar é principalmente questão de disciplina, não magia.getStaticProps. The migration itself is the dangerous part. Getting it right is mostly about discipline, not magic.

---

Por Que Esta Migração Quebra SEO Em Primeiro Lugar

A coisa que a maioria dos tutoriais deixa passar batido é esta: WordPress faz uma quantidade enorme de trabalho pesado de SEO para você sem você perceber. Yoast ou Rank Math está gerando suas meta tags. WordPress core está tratando sua estrutura de permalink. Seu tema provavelmente está outputando algum tipo de markup de schema. Seu XML sitemap se regenera automaticamente toda vez que você publica.some kind of schema markup. Your XML sitemap auto-regenerates every time you publish.

Quando você puxa a camada de conteúdo para Next.js via API WPGraphQL e a serve de um novo front-end, toda aquela infraestrutura vira seu problema para replicar. Cada. Peça. Uma.WPGraphQL API and serve it from a new front-end, all of that infrastructure becomes your problem to replicate. Every. Single. Piece.

O outro problema é a estrutura de URL. A maioria dos sites WordPress tem /category/post-slug/ ou /year/month/post-slug/ ou apenas /post-slug/. Next.js oferece uma tela em branco para roteamento. Essa tela em branco é um cemitério de rankings se você não planejar cuidadosamente./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.

Os Dois Modos de Falha que Vejo Constantemente

A primeira é times que migram as URLs também e ainda quebram as coisas -- geralmente porque redirects são aplicados inconsistentemente ou o novo sitemap vai ao ar antes dos redirects. A segunda é times que intencionalmente mudam a estrutura de URL (muitas vezes para limpá-la) e tratam o mapeamento de redirect como uma coisa menor. Ambas são consertáveis. Nenhuma é aceitável.

---

Audite Antes de Tocar em Qualquer Coisa

Não escreva uma única linha de código Next.js antes de ter um inventário de URL completo. Eu uso Screaming Frog -- faço o crawl do site WordPress ativo, exporto toda URL indexável, e despejo em uma planilha. Para um site de 400 páginas são talvez uma hora de trabalho. Para um site de 4 mil páginas ainda é só uma hora, porque a ferramenta faz automaticamente.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.

O que você está capturando:

  • Cada URL canônico atualmente indexado
  • O status HTTP de cada um (identifique 404s e 301s que já existem)
  • O meta title e description de cada página
  • Quais páginas têm structured data (use o Rich Results Test ou inspecione apenas o fonte)
  • Links internos de entrada -- para você saber quais páginas linkam para quais

Também puxe seus top 50 páginas do Google Search Console ordenadas por cliques. Essas são as que você não pode se dar ao luxo de errar. Sinalize-as na planilha. Trate-as como dependências de produção.

Seahawk tinha um cliente de e-commerce no final de 2022 -- loja WooCommerce de 1.200 produtos mudando para uma estrutura headless. Passamos dois dias inteiros no audit antes de escrever código. O cliente achava que estávamos perdendo tempo. Salvamos as 90 mil sessões orgânicas mensais deles.

---

Configurando WordPress como um Verdadeiro Headless CMS

Essa parte é principalmente direta. Instale WPGraphQL e exponha seu conteúdo via GraphQL API. Mas há algumas coisas que valem ser deliberado sobre.

Mantenha Yoast (ou Rank Math) Rodando no Lado do WordPress

Mesmo que você não esteja mais servindo WordPress como o front-end público, mantenha seu plugin SEO ativo. WPGraphQL for Yoast SEO (ou a extensão Rank Math equivalente) expõe todos os meta SEO -- títulos, descrições, URLs canônicas, dados OG, diretivas robots -- direto através da API GraphQL. Isso significa que você pode fazer query dela do Next.js e renderizar exatamente como Yoast pretendia.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.

Essa foi a lição daquele drop de tráfego de 2019 que mencionei. Eu tinha assumido que conseguiríamos regenerar títulos a partir do título do post + nome do site em Next.js. Conseguíamos. Mas o Yoast tinha customizado manualmente meta titles para cerca de 80 dos posts com melhor desempenho, e a gente apagou tudo isso. Oito semanas para se recuperar.

Desabilite o Front-End do WordPress com Cuidado

Uma vez que você está pronto para apontar tráfego para Next.js, você NÃO quer WordPress servindo seu próprio front-end simultaneamente. Conteúdo duplicado em escala. A forma mais limpa é colocar um robots.txt em sua instalação WordPress com Disallow: / enquanto seu site Next.js vai ao ar, depois eventualmente fazer firewall da URL do WordPress inteiramente para que seja acessível apenas internamente 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.

Não pule a etapa do robots.txt. Já vi times bloquearem WordPress no nível do CDN e depois descobrirem que o Googlebot tinha uma rota em cache. Leva meses para limpar.

---

Replicando a Estrutura de URLs Exatamente

Minha recomendação padrão forte: mantenha suas URLs idênticas. Mesmo slug, mesma estrutura de permalink, mesmo comportamento de trailing slash. Quanto mais as rotas do Next.js espelharem as rotas do WordPress, menos redirects você precisará, e menos risco você carrega.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.

Dynamic routes do Next.js tornam isso fácil. Se seus posts WordPress vivem em /blog/[slug], crie pages/blog/[slug].js. Pronto.dynamic routes make this easy. If your WordPress posts live at/blog/[slug], create pages/blog/[slug].js. Done.

Onde fica bagunçado é com archive de categorias, páginas de autor, páginas de tag, e archives paginados (/blog/page/2/). WordPress gera tudo isso automaticamente. Em Next.js você está construindo eles mesmo. Muitos times deprioritizam esses e depois se perguntam por que a cobertura de crawl caiu./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.

Aqui está meu checklist numerado para paridade de URL:

  1. Posts/páginas únicas -- combine o slug exatamente, incluindo qualquer subpasta -- match the slug exactly, including any subfolder
  2. Arquivos de categoria -- recrie /category/[slug]/ com getStaticPaths puxando todas as categorias de WPGraphQL -- recreate/category/[slug]/with getStaticPaths pulling all categories from WPGraphQL
  3. Arquivos de tag -- igual ao acima, não pule estes se receberem tráfego orgânico -- same as above, don't skip these if they get organic traffic
  4. Arquivos de autor -- verifique o Search Console primeiro; se receberem zero cliques, você pode fazer 301 para a homepage -- check Search Console first; if they get zero clicks, you can 301 them to the homepage
  5. Arquivos paginados -- /blog/page/[num]/ vale a pena preservar se você tiver muitos posts -- /blog/page/[num]/is worth preserving if you have a lot of posts
  6. Páginas de anexo -- quase sempre faça 301 destas para o post pai; elas são peso morto em SEO no WordPress também -- almost always 301 these to the parent post; they're SEO dead weight in WordPress too
  7. URLs de feed -- /feed/ deve fazer 301 para seu novo feed RSS se tiver um, ou retornar 410 se não tiver -- /feed/should 301 to your new RSS feed if you have one, or return 410 if not

---

Redirecionamentos: A Parte Que Todo Mundo Subestima

Se você está mudando quaisquer URLs -- o que eu questionaria, mas às vezes é necessário -- seu mapa de redirecionamento precisa ser construído antes do lançamento e testado em um ambiente 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.

No Next.js, redirecionamentos vivem em next.config.js. Para sites pequenos (menos de 200 redirecionamentos) tudo bem. Para qualquer coisa maior, coloque em um arquivo JSON e importe, ou use middleware para lidar com eles dinamicamente. O edge middleware do Vercel é excelente para tabelas grandes de redirecionamento porque funciona antes da página ser renderizada -- zero penalidade de latência.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.

O formato em 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 envia um 301. Use para todas as mudanças de URL genuínas. Não use 302 (temporário) a menos que você realmente intenda revertê-lo -- Google trata muito diferente. 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.

Teste cada redirecionamento antes do lançamento. Uso um script bash simples que passa pela planilha e faz curl de cada URL antiga verificando uma resposta 301 para o destino correto. Leva dez minutos para escrever, economiza horas de pânico pós-lançamento.

---

Meta Tags, URLs Canônicas e Dados Estruturados no Next.js

É aqui que a maioria das migrações perde pontos silenciosamente. O conteúdo está lá, as URLs funcionam, mas os sinais de SEO estão errados.

Meta Tags

Use next-seo. É o padrão. Passe os dados que você consultou do WPGraphQL Yoast. Seu app.js recebe uma configuração DefaultSeo, e cada página recebe um componente NextSeo com as substituições específicas da página. Pegue o título, descrição, título OG, imagem OG, URL canônica e diretivas robots diretamente da resposta GraphQL do Yoast -- não reinvente.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.

Uma coisa que pega as pessoas: URLs canônicas. No WordPress, o Yoast define canônicas automaticamente. No Next.js você precisa passar a canônica explicitamente. Se esquecer, o Next.js renderizará páginas sem a tag canônica, e se você tiver query strings em qualquer lugar (paginação, filtros), você terá problemas de conteúdo duplicado mais rápido do que esperaria.

Dados Estruturados

Temas e plugins WordPress frequentemente geram JSON-LD automaticamente. Isso desaparece em headless. Você precisa reconstruir. Para artigos, use o schema Article. Para produtos, Product. Para negócios locais, LocalBusiness. Escrevo esses como componentes React que aceitam props e retornam uma tag <script type="application/ld+json">. Um componente por tipo de schema, reutilizado em toda a app.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.

Verifique cada tipo de schema que você tinha antes na Rich Results Test antes da migração. Documente. Recrie. Teste os novos com a mesma ferramenta após o lançamento.before migration. Document them. Recreate them. Test the new ones with the same tool post-launch.

O XML Sitemap

Não use um sitemap estático. Gere-o dinamicamente. Para sites pequenos, getServerSideProps em uma rota /sitemap.xml funciona. Para sites grandes com milhares de posts, gere o sitemap no tempo de construção via um script customizado e exporte para a pasta public/. Vercel executa isto em cada deployment -- seu sitemap está sempre atual.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.

Envie a nova URL do sitemap para o Google Search Console no primeiro dia do novo site ao vivo. Não no terceiro dia. No primeiro dia.

---

Monitoramento Pós-Lançamento (A Janela de 90 Dias)

A migração não termina no lançamento. Termina quando seus rankings se estabilizarem -- o que a documentação do Google sugere que pode levar de algumas semanas a alguns meses, dependendo do crawl budget e da autoridade do site.

O que monitoro toda semana no primeiro mês:

  • Google Search Console → relatório Coverage procurando por novos 404s ou URLs 'Excluded' que não deveriam estar excluídos for new 404s or 'Excluded' URLs that shouldn't be excluded
  • Search Console → Performance -- compare cliques e impressões semana a semana para suas 50 páginas principais -- compare clicks and impressions week-on-week for your top 50 pages
  • Recrawl do Screaming Frog do site novo para pegar qualquer 404 interno ou tags canonical mal configuradas of the new site to catch any internal 404s or misconfigured canonical tags
  • Core Web Vitals -- sim, o site Next.js deveria ser mais rápido, mas verifique nos dados de campo (CrUX), não apenas no Lighthouse -- yes, the Next.js site should be faster, but verify it in the field data (CrUX), not just Lighthouse

Se vir uma queda significativa nas primeiras duas ou três semanas, não entre em pânico imediatamente. Quase sempre há uma flutuação de curto prazo enquanto o Google re-rastreia e re-indexa. O que você procura é quedas sustentadas após a semana quatro. Esse é o sinal de que algo estrutural está errado.

No final de 2022 -- projeto diferente do de e-commerce -- lançamos uma migração Next.js para um blog SaaS e vimos uma queda de 20% em impressões na segunda semana. Descobrimos que nosso sitemap gerado dinamicamente estava incluindo páginas com noindex porque não tínhamos filtrado a query do WPGraphQL corretamente. Corrigimos em quatro horas. Os rankings se recuperaram em três semanas. O monitoramento detectou antes de piorar.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

Quanto tempo leva uma migração de WordPress para Next.js?

Honestamente, depende mais da complexidade do site do que da quantidade de posts. Um site institucional com 100 páginas e URLs limpas pode ser feito corretamente em duas a três semanas. Um blog com 2.000 posts, tipos de post customizados, campos ACF e integração WooCommerce é um projeto de mínimo seis a oito semanas se você estiver fazendo o trabalho de SEO corretamente junto com o desenvolvimento. Não deixe ninguém te contar que é um trabalho de fim de semana.

Devo usar o Pages Router ou o App Router no Next.js?

A partir de meados de 2024 estou usando o App Router por padrão para novos projetos. Mas se sua equipe está mais confortável com o Pages Router e esta é uma migração com prazo apertado, use o que vocês conhecem. As implicações de SEO são mínimas -- ambos suportam geração estática, renderização no servidor e rotas dinâmicas. O pacote next-seo agora também tem suporte ao App Router.next-seo package has App Router support now too.

Preciso sair do WordPress hosting completamente?

Não. WordPress pode ficar no seu host existente -- WP Engine, Kinsta, Cloudways, o que quer que vocês estejam usando -- e agir puramente como uma API de conteúdo. O front-end Next.js faz deploy no Vercel ou Netlify. Os dois se comunicam via HTTP. Alguns clientes na verdade preferem isso porque o time editorial mantém o WordPress admin que já conhecem.Netlify. The two communicate via HTTP. Some clients actually prefer this because the editorial team keeps the WordPress admin they already know.

E quanto aos plugins do WordPress que afetam SEO -- como redirecionamentos gerenciados em Redirection?

Exporte-os antes de migrar. O plugin Redirection tem exportação para CSV. Pegue todos esses redirecionamentos existentes e adicione-os ao seu next.config.js ou edge middleware. Não assuma que eles serão transferidos automaticamente -- não serão, porque vivem no banco de dados do WordPress e Next.js não sabe que existem.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.

Meu ranking no Google vai cair não importa o quê?

Há quase sempre alguma volatilidade de curto prazo. Uma migração bem executada sem mudanças de URL, com redirecionamentos apropriados (onde necessário), meta e dados estruturados replicados, e sitemap reenviado deve se estabilizar em quatro a seis semanas. As quedas que durei meses foram todas causadas por erros técnicos específicos -- não pela migração em si.

---

A migração não é a parte difícil. A parte difícil é a disciplina de fazer cada passo chato, sem glamour -- a auditoria, o mapeamento de redirecionamentos, a recriação de schema -- antes de escrever qualquer código Next.js inteligente. Acerte essa ordem e você sairá do outro lado com um front-end mais rápido e os mesmos rankings com que começou. Possivelmente melhores, uma vez que as melhorias de Core Web Vitals entrarem em efeito.Core Web Vitals improvements feed through.

< BACK