Alex Amigo
SEO

Lo que encuentro cuando audito una web hecha con Next.js, Nuxt o Astro

Alex Amigo9 min de lectura

Cuando audito una web hecha con Next.js, Nuxt o Astro, los problemas de indexación que encuentro rara vez son los que el equipo de desarrollo esperaba. El tipo de renderizado declarado en el código no garantiza que Google vea lo mismo que el navegador, y esa brecha es la fuente de casi todos los fallos que aparecen en estas auditorías.

Cuando alguien me manda a auditar una web hecha con Next.js, Nuxt o Astro, casi siempre viene con la misma certeza: «es que tiene SSR, así que Google no debería tener ningún problema». A veces añaden que migraron desde una web en React puro precisamente para resolver los problemas de indexación que tenían antes. Y entonces abro el View Source de la URL principal y veo un <div id="__next"></div> completamente vacío.

Esto no es un caso raro. En los últimos meses me he encontrado con este escenario en webs construidas por equipos con buen nivel técnico, proyectos con presupuesto real y arquitecturas que sobre el papel tenían todo el sentido del mundo. El problema no es el framework; el problema es que existe una brecha enorme entre lo que el código declara que hace y lo que Google realmente ve cuando rastrea la página.

Por qué los frameworks modernos crean problemas de indexación que el JS SEO clásico no atrapa

Cuando hablamos de «problemas de JavaScript y SEO», la mayoría de la gente piensa en el escenario clásico: una Single Page Application (SPA) que renderiza todo en el cliente, Google encuentra HTML vacío y no indexa nada. Ese problema está bien documentado, y buena parte de los equipos que trabajan con estos frameworks lo conocen. Lo que ya no está tan documentado es que Next.js, Nuxt y Astro introducen modelos de renderizado mucho más granulares, y esa granularidad es exactamente lo que genera los fallos que el JS SEO clásico no atrapa.

En estos frameworks coexisten cuatro estrategias de renderizado: SSR (generación del HTML en servidor en cada petición), SSG (generación estática en tiempo de build), ISR (regeneración incremental con intervalos configurables) y CSR (renderizado en cliente, el problemático de siempre). La diferencia con las SPAs antiguas es que ahora no tienes una estrategia para toda la web, sino que cada ruta puede estar usando una distinta, y eso incluye rutas que el desarrollador no configuró explícitamente, que por defecto caen en CSR.

El error conceptual que veo con más frecuencia es asumir que «usar Next.js» equivale a «tener SSR». Next.js tiene SSR, pero también tiene CSR, y si no configuras explícitamente la estrategia de cada ruta, el framework toma decisiones por ti que no siempre son las que SEO necesita. Hay páginas de producto, páginas de categoría y landings de conversión que acaban en CSR porque nadie tomó esa decisión conscientemente; simplemente no se tomó ninguna, y el framework aplicó su comportamiento por defecto.

Los tres patrones de fallo que aparecen en casi todas las auditorías de Next.js y Nuxt

Después de varias auditorías de webs construidas con estos frameworks, los problemas se concentran en tres patrones que aparecen con una regularidad que ya me resulta predecible.

El primero es CSR donde debería haber SSG o SSR. La manifestación en auditoría es simple: abres el View Source de la URL y el body está vacío o contiene solo el wrapper del framework (<div id="__next"> en Next.js, <div id="__nuxt"> en Nuxt). El contenido visible en el navegador no está en el HTML que Google descarga cuando rastrea; está generado en JavaScript después de que el archivo llega al cliente. En páginas de contenido estático —una ficha de producto, una página de servicio, un artículo de blog— no hay ninguna razón técnica para estar en CSR; está ahí porque no se configuró lo contrario.

El segundo patrón son los metadatos generados en cliente. Esto es especialmente frecuente en migraciones donde el equipo de desarrollo montó la lógica de titles y meta descriptions dentro de componentes que se ejecutan en el cliente, no en el servidor. En la auditoría lo ves inmediatamente: el Screaming Frog con renderizado JS desactivado muestra los campos de title y meta description vacíos, o con valores genéricos de plantilla sin reemplazar. Google puede llegar a ver el metadato correcto si espera lo suficiente a que el JavaScript se ejecute, pero no es algo en lo que valga la pena confiar para páginas que necesitan indexarse bien.

El tercero son los soft 404 en rutas dinámicas. Una ruta dinámica que no encuentra el recurso que busca —un producto descatalogado, una URL con parámetro incorrecto, una categoría vacía— devuelve un código HTTP 200 pero muestra en pantalla un mensaje de error o una página vacía. Google rastrea esa URL, recibe el 200, intenta indexarla y acaba con una página sin contenido en su índice; o la reporta en la cobertura de Search Console como «Rastreado, actualmente no indexado» sin que sea obvio por qué. Este es el patrón que más trabajo cuesta comunicar a los equipos de desarrollo, porque desde el servidor el comportamiento parece correcto; el problema está en que el framework no está propagando el estado de error al código de respuesta HTTP.

Cómo diagnosticarlo antes de tocar ningún archivo de configuración

El orden del diagnóstico importa tanto como las herramientas que usas. El error habitual es lanzar Screaming Frog con renderizado JS activado desde el principio y pasar horas procesando datos que el View Source ya te habría dado en cinco minutos.

Empiezo siempre por el View Source de las URLs más críticas: la home, las páginas de categoría principales y una muestra de páginas de contenido. Si el HTML raw tiene el contenido visible —títulos, párrafos, nombres de producto— el framework está sirviendo ese contenido desde servidor y puedo descartar el primer y el segundo patrón para esas URLs. Si el body está vacío o casi vacío, ya tengo el diagnóstico antes de abrir ninguna herramienta.

Cuando el View Source ya muestra el problema, no tiene sentido ir a Screaming Frog todavía; lo que toca es documentar qué rutas tienen el HTML vacío y cuáles no, para tener una imagen de la magnitud antes de la reunión con el equipo técnico. Cuando el View Source está limpio pero hay URLs en el informe de cobertura de GSC que no se indexan, ahí sí entro con Screaming Frog con dos pasadas: una sin renderizado JS y otra con renderizado activado. La diferencia entre lo que encuentra Screaming Frog en cada pasada es exactamente la brecha que ve Google entre el HTML que descarga y el contenido que puede llegar a procesar.

Para los soft 404, el mejor punto de entrada es el informe de Cobertura de GSC, filtrado por el estado «Rastreado, actualmente no indexado». Las URLs que aparecen ahí y que, al revisarlas manualmente, muestran contenido de error o páginas vacías son candidatas claras a ser soft 404. La confirmación definitiva es combinar ese listado con una revisión manual de los códigos de respuesta HTTP reales de esas URLs; cualquier herramienta que compruebe códigos de estado sirve para eso.

Qué puedes hacer sin tocar el código y qué necesita al desarrollador

Una de las preguntas que me hacen casi siempre al presentar el diagnóstico es cuánto se puede solucionar sin involucrar al equipo de desarrollo, porque eso determina los plazos y la prioridad interna del proyecto. La respuesta honesta es que sin el desarrollador se puede avanzar poco en los problemas de fondo, pero hay acciones que vale la pena tomar de inmediato.

Sin tocar código puedes verificar si hay etiquetas de indexación (noindex) añadidas por error en producción; esto ocurre con más frecuencia de la que parece en proyectos que migraron de staging a producción sin revisar la configuración. También puedes sentarte con el desarrollador y revisar en el código cómo está implementada la lógica de metadatos, sin necesidad de cambiar nada todavía; en Next.js, por ejemplo, la diferencia entre generar el title en el Head del cliente o usando la API de generateMetadata en el servidor es un cambio de pocas líneas, pero la conversación solo puede ocurrir si sabes exactamente qué buscar. Por último, si tienes acceso a las herramientas de analítica del proyecto, puedes cruzar las URLs con tráfico orgánico bajo y las URLs reportadas como «rastreadas, no indexadas» para priorizar cuáles hay que arreglar primero; eso no requiere tocar nada del código y le da al desarrollador un listado accionable en lugar de un problema difuso.

Lo que sí necesita al desarrollador —y no hay atajos aquí— es cambiar la estrategia de renderizado de rutas específicas de CSR a SSG o SSR. En Next.js con el App Router, eso implica ajustar la configuración de cada ruta o segmento para que exporte el contenido desde servidor. En Nuxt, el comportamiento universal de SSR facilita este cambio en muchos casos, pero las rutas con datos dinámicos que se están cargando en el cliente requieren mover esa lógica al composable de servidor. Son cambios que un desarrollador familiarizado con el framework puede hacer en poco tiempo, pero requieren saber exactamente qué rutas tienen el problema y qué estrategia de renderizado encaja con la naturaleza de esa página.

El cierre que me parece más honesto después de estas auditorías es este: si la arquitectura de renderizado se planificó mal desde el principio, un parche de metadatos no arregla el fondo. Puedes tener titles perfectos, meta descriptions optimizadas y un sitemap impecable, pero si Google está rastreando HTML vacío en las páginas más importantes del proyecto, ninguna de esas optimizaciones va a mover la aguja de indexación. El problema es estructural y necesita una solución estructural; lo demás son detalles que solo tienen sentido una vez que el HTML que Google ve tiene contenido real.

Preguntas frecuentes

Si mi web usa Next.js con App Router, ¿puede tener problemas de indexación aunque tenga SSR?

Sí, y es más frecuente de lo que parece. El App Router de Next.js permite mezclar componentes de servidor y de cliente en la misma ruta; si los componentes que generan el contenido principal están marcados como Client Components, ese contenido se renderiza en el navegador, no en el servidor. Google puede ver HTML vacío aunque el proyecto declare que usa SSR. La comprobación más rápida es el View Source: si el body está vacío o contiene solo el wrapper del framework, tienes un problema de renderizado independientemente de la tecnología usada.

¿Astro tiene los mismos problemas de indexación que Next.js o Nuxt?

Astro tiene un comportamiento por defecto distinto: genera HTML estático en build, lo que hace que View Source muestre el contenido completo en la mayoría de los casos. El problema aparece cuando se usan islas interactivas con frameworks de UI (React, Vue, Svelte) en modo 'client:load' o 'client:only' para contenido que debería estar en el HTML estático. En esos casos, Astro tiene el mismo problema que cualquier otro framework: Google descarga HTML sin ese contenido. No es tan frecuente como en Next.js, pero sí aparece en proyectos donde se migró contenido dinámico a componentes de isla sin pensar en el impacto SEO.

¿Cuánto tarda en indexarse una web de Next.js una vez que se corrige la configuración de renderizado?

Depende de la autoridad del dominio y de la frecuencia de rastreo que Google tenga asignada al sitio. Para webs con rastreo activo, los cambios en la generación del HTML suelen reflejarse en el índice entre dos y seis semanas después de que Googlebot rerastre las URLs corregidas. Se puede acelerar el proceso enviando las URLs más importantes a través de la herramienta de Inspección de URL en Google Search Console, aunque para volúmenes grandes lo más eficiente es asegurarse de que el sitemap está actualizado y que la estructura de enlazado interno apunta bien a las páginas corregidas.

Alex Amigo
Alex Amigo

Desarrollo, SEO, GEO y tecnología con una visión de negocio.