SEO de aplicaciones SPA: por qué las SPA no posicionan, cómo lo resuelven el SSR, la generación estática y el prerenderizado, y cómo hacer que las IA las lean.

En resumen
una aplicación de una sola página (SPA, por sus siglas en inglés) carga un único armazón HTML y construye cada vista con JavaScript en el navegador. Google puede renderizar JavaScript, pero ese renderizado llega con retraso y es frágil, y los rastreadores de ChatGPT, Claude y Perplexity no lo ejecutan en absoluto. Para posicionar y ser citada, cada vista de una SPA necesita su propia URL, un enlace real con href, un título y una descripción únicos, un código de estado correcto y, sobre todo, su contenido principal presente en el HTML que envía el servidor, mediante renderizado del lado del servidor, generación estática o prerenderizado.
¿Quiere ir más lejos? Pregunte a
El SEO de aplicaciones SPA es el conjunto de técnicas que hacen que una aplicación JavaScript creada con React, Vue, Angular o Svelte sea tan fácil de rastrear como un sitio web clásico. El problema está bien documentado: Google explica en sus conceptos básicos de SEO para JavaScript que procesa las páginas JavaScript en tres fases (rastreo, renderizado, indexación), y cada debilidad de una SPA se sitúa en algún punto de esa cadena. Esta guía se centra en las SPA; para los sitios JavaScript en general, lea nuestra guía de SEO para JavaScript.
Un sitio web tradicional devuelve un documento HTML completo para cada URL. Una SPA devuelve casi el mismo documento para todas las URL: un <div id="root"> vacío, unas pocas metaetiquetas y un gran paquete de JavaScript. El navegador descarga el paquete, llama a una API y después dibuja la página. Cuando el visitante hace clic en un enlace, JavaScript cambia el contenido sin recargar.
Para una persona con un móvil rápido, el resultado parece instantáneo. Para un rastreador, la primera respuesta es un armazón vacío: sin encabezado, sin texto, sin enlaces. Todo depende de si el bot ejecuta el JavaScript, y de cuándo lo hace. Ese único hecho explica la mayoría de los problemas de SEO de las SPA:
/#/pricing), y la parte que sigue al # nunca se envía al servidor, de modo que todas las vistas se reducen a una sola URL.<title> y, si el enrutador no lo actualiza, todas las páginas lo comparten.href: los botones y los controladores onClick permiten navegar a los usuarios, pero no dan a los rastreadores nada que seguir.Googlebot obtiene primero el HTML sin procesar y lee los enlaces y las directivas que encuentra en él. Las páginas que devuelven un estado 200 pasan después a una cola del Web Rendering Service, un Chromium sin interfaz gráfica. Google indica que una página «puede permanecer en esta cola unos segundos, pero puede tardar más». Una vez renderizada, el HTML resultante se analiza de nuevo en busca de contenido y enlaces, y luego se indexa.
Cuatro detalles de la documentación de Google importan para las SPA:
<a> con href son enlaces fiables. Los enlaces insertados por JavaScript funcionan siempre que respeten ese formato.pushState) en lugar de rutas con #. Dejó obsoleto su antiguo esquema de rastreo AJAX (las URL con #!) en octubre de 2015.noindex en el HTML original prevalece. Google puede omitir el renderizado cuando ve noindex, así que quitarlo después con JavaScript no funciona.La consecuencia es clara: Google puede indexar una SPA renderizada del lado del cliente, pero usted añade a cada página un segundo paso, un retraso y un punto de fallo. Un tiempo de espera agotado, una llamada a la API bloqueada o un error de JavaScript durante el renderizado dejan vacía la versión indexada. Compruebe lo que ve Google con la herramienta de inspección de URLs de Search Console y lea nuestra guía sobre cómo funciona la indexación de Google si hay páginas que no entran en el índice.
En su mayoría, no. En un estudio publicado en diciembre de 2024 sobre el tráfico de su red, Vercel y MERJ comprobaron que «ninguno de los principales rastreadores de IA renderiza JavaScript actualmente»: GPTBot, OAI-SearchBot y ChatGPT-User (OpenAI), ClaudeBot (Anthropic), PerplexityBot, Meta-ExternalAgent y Bytespider leen solo el HTML sin procesar. Sí descargan archivos JavaScript (alrededor del 11,5 % de las solicitudes de ChatGPT y del 23,8 % de las de Claude), pero no los ejecutan. Las excepciones son Gemini, que se apoya en la infraestructura de renderizado de Google, y AppleBot, que utiliza un rastreador basado en navegador.
Para una SPA renderizada del lado del cliente, esto significa que los rastreadores de IA que alimentan ChatGPT, Claude y Perplexity ven una página vacía. Su producto puede posicionar en Google y seguir siendo invisible en las respuestas de las IA, porque el asistente nunca ha leído ni una palabra. Lo mismo ocurre con la mayoría de los bots de vista previa de enlaces de las redes sociales y de las aplicaciones de mensajería, que leen las etiquetas Open Graph en el HTML sin procesar. Una vez que el contenido esté en el HTML, compruebe también que su robots.txt permite los rastreadores de IA que desea.
La solución es enviar HTML real desde la primera respuesta. En su documentación sobre el renderizado dinámico, Google califica el renderizado dinámico (servir una versión prerenderizada solo a los bots) de «solución alternativa» que no recomienda, y remite en su lugar al renderizado del lado del servidor, al renderizado estático o a la hidratación. Las definiciones siguientes se basan en la referencia Rendering on the Web de web.dev.
| Estrategia | Cómo funciona | Contenido en el primer HTML | Ideal para | Límites |
|---|---|---|---|---|
| Renderizado del lado del cliente (CSR) | El navegador construye la página a partir de JavaScript y una API | No | Paneles de control y páginas tras un inicio de sesión | Indexación retrasada en Google, invisible para la mayoría de los rastreadores de IA |
| Renderizado del lado del servidor (SSR) | El servidor genera el HTML en cada solicitud y luego JavaScript lo hidrata | Sí | Catálogos, listados, contenido que cambia a menudo o personalizado | Coste de servidor, tiempo de respuesta más lento sin caché |
| Generación estática (SSG) | El HTML se genera en la compilación para cada URL y se sirve desde una CDN | Sí | Páginas de marketing, blog, documentación, páginas de destino | Hay que recompilar cuando cambia el contenido (existen opciones incrementales) |
| Prerenderizado en la compilación | Un navegador sin interfaz captura el estado inicial de cada ruta como HTML estático | Sí | SPA existentes con un número limitado de rutas públicas | Datos congelados en la compilación, hay que listar las rutas |
| Renderizado dinámico | Los bots reciben una captura prerenderizada y los usuarios, la SPA | Sí, solo para los bots listados | Solución temporal para una aplicación antigua | Oficialmente una solución alternativa, coste de mantenimiento, riesgo de servir a los bots un contenido distinto |
La mayoría de los frameworks modernos permiten combinar estrategias por ruta: estática para las páginas de marketing, renderizada en el servidor para el catálogo y renderizada en el cliente para la aplicación con sesión iniciada. Esta configuración híbrida ofrece a los rastreadores HTML completo allí donde llega el tráfico de búsqueda y mantiene la experiencia SPA allí donde aporta valor.
| Biblioteca | Framework o función para tener HTML en la primera carga |
|---|---|
| React | Next.js (componentes de servidor, SSR y generación estática), React Router en modo framework, Gatsby |
| Vue | Nuxt (renderizado universal por defecto, generación estática disponible) |
| Angular | Angular SSR (renderizado en el servidor y prerenderizado en la compilación) |
| Svelte | SvelteKit (renderizado en el servidor por defecto, prerenderizado por ruta) |
| Cualquiera de ellas | Astro (HTML estático por defecto, islas interactivas cargadas solo donde hacen falta) |
Los sitios generados con creadores de webs basados en IA merecen una mención especial: muchos exportan una aplicación React renderizada del lado del cliente. Si ha creado su sitio con uno de ellos, consulte nuestras notas sobre SEO y GEO en Lovable antes de dar por hecho que Google y ChatGPT pueden leerlo.
Utilice la History API (/pricing, nunca /#/pricing), una URL por contenido y la misma URL tanto si el visitante llega directamente como si navega dentro de la aplicación. Cada URL debe cargar el contenido correcto al abrirse en una pestaña nueva: es la prueba que realiza un rastreador.
Todo elemento de navegación que lleve a una página indexable debe ser un <a href="/path">. Los componentes de enlace de los frameworks (Link, NuxtLink, routerLink) generan este marcado; los controladores de clic personalizados en elementos div o button, no. Los buenos enlaces también sostienen la arquitectura de su sitio: si una página no recibe enlaces, los rastreadores rara vez la encuentran.
Cada ruta necesita su propio título, su metadescripción, su URL canónica y sus etiquetas Open Graph, generados en el servidor siempre que sea posible. Nuestra página sobre metaetiquetas enumera lo que hay que definir. Mantenga una sola etiqueta canónica: Google recomienda definirla en el HTML y, si JavaScript la modifica, el resultado no debe contradecir el original.
Los productos inexistentes y los artículos eliminados no deben responder 200 con un mensaje de error. Con SSR, devuelva un 404 o un 410 real desde el servidor. En una SPA pura, Google acepta dos alternativas: redirigir con JavaScript a una URL que devuelva un 404 o añadir una metaetiqueta robots noindex a la vista de error.
Los encabezados, el texto, los precios, las preguntas frecuentes y los datos estructurados JSON-LD deben estar en la respuesta del servidor, no cargarse después de un clic o un desplazamiento. El contenido oculto tras pestañas que se renderizan bajo demanda, o tras botones de «Cargar más», a menudo se pierde.
Divida el paquete por rutas, aplace lo que no sea necesario para la primera vista y evite volver a renderizar toda la página durante la hidratación. Tenga en cuenta que los datos de campo de Chrome (CrUX) atribuyen las métricas de las navegaciones dentro de la aplicación a la URL que el visitante cargó primero, así que pruebe sus plantillas clave una por una.
Compare tres versiones de cada plantilla clave: el HTML sin procesar (vea el código fuente u obtenga la página con una herramienta de línea de comandos), el HTML renderizado por Google (Inspección de URLs y después «Ver página rastreada») y la página con JavaScript desactivado. Si el texto principal solo aparece en la segunda versión, los rastreadores de IA no lo ven. Nuestra auditoría de rastreabilidad para IA gratuita y el comprobador de indexabilidad realizan estas verificaciones en cualquier URL.
| Síntoma | Causa probable | Solución |
|---|---|---|
| Search Console muestra muchas páginas «Rastreada: actualmente sin indexar» | HTML vacío o casi idéntico antes del renderizado | SSR, SSG o prerenderizado para las rutas públicas |
Todos los resultados de una búsqueda site: muestran el mismo título | Título no actualizado por ruta | Gestión del encabezado HTML por ruta en el servidor |
| Solo está indexada la página de inicio | Enrutamiento con almohadilla o enlaces sin href | History API y enlaces <a> reales |
| Aparecen páginas de error en el índice | Soft 404 (estado 200 en todas partes) | 404 del servidor, redirección JavaScript a una URL 404 o noindex |
| Posiciona en Google pero nunca lo citan ChatGPT ni Perplexity | Contenido visible solo tras ejecutar JavaScript | Contenido en la primera respuesta HTML |
| Contenido antiguo en la vista renderizada de Google | Archivos JavaScript o CSS en caché | Nombres de archivo con huella |
Durante años, el renderizado del lado del cliente fue un riesgo asumible, porque Google acababa renderizando el JavaScript. Ahora que parte del descubrimiento ocurre en ChatGPT, Claude, Gemini y Perplexity, el coste ha cambiado: una página que solo existe tras ejecutar JavaScript no figura entre las fuentes que la mayoría de los asistentes pueden leer. La rastreabilidad en el HTML sin procesar se ha convertido en la primera condición de la optimización para motores generativos (GEO).
Una vez completo el HTML, lo demás sigue las reglas habituales: las páginas que responden con claridad a una pregunta, con datos con fuente y datos estructurados, son las que citan los asistentes. Las funciones de optimización GEO de Sorank le ayudan a redactar y publicar ese contenido, y el seguimiento de menciones en IA muestra si ChatGPT, Claude y Gemini citan su marca después de corregir el renderizado.
La regla clave del SEO de aplicaciones SPA cabe en una frase: todo lo que quiera que Google posicione y que las IA citen debe estar en el HTML que envía el servidor. Reserve la SPA para la experiencia con sesión iniciada, renderice las páginas públicas en el servidor o en la compilación y compruebe lo que reciben los bots antes y después de cada lanzamiento.
Google no penaliza una aplicación de una sola página, pero su configuración por defecto, el renderizado del lado del cliente con un único armazón HTML, hace que la indexación sea más lenta y menos fiable. La mayoría de los rastreadores de IA no ejecutan JavaScript, así que ven una página vacía. Con renderizado del lado del servidor, generación estática o prerenderizado en las rutas públicas, una SPA puede posicionar tan bien como cualquier sitio web clásico.
React en sí es neutral: lo que importa es dónde se genera el HTML. Una aplicación React renderizada solo en el navegador tiene los problemas habituales de las SPA, mientras que los mismos componentes renderizados en el servidor con Next.js o React Router en modo framework entregan HTML completo a los rastreadores. Elija un framework que admita renderizado en el servidor o estático para las páginas que quiera indexar.
Solo como medida temporal. Google describe el renderizado dinámico como una solución alternativa que no recomienda, porque mantener una versión separada para los bots añade costes y riesgos. El renderizado del lado del servidor, la generación estática o el prerenderizado en la compilación ofrecen el mismo HTML a todos los visitantes y son las soluciones a largo plazo.
PROBARON SORANK ANTES QUE USTED
