Por qué las single page apps tienen problemas en los buscadores y cómo arreglarlo: SSR, generación estática o prerenderizado, títulos por ruta en React 19 o con react-helmet-async, URLs reales, soft 404, sitemaps, Inspección de URLs y un comprobador del código fuente.
Las single page apps suelen enviar a los buscadores un HTML casi vacío y construyen la página después con JavaScript. Google puede renderizar JavaScript, pero lo hace con retraso, y otros rastreadores puede que no lo hagan. La solución es servir HTML real para cada URL mediante renderizado en el servidor, generación estática o prerenderizado, con un título, una descripción y un canonical únicos en cada ruta.
Las tres soluciones que más importan
Este sitio es en sí mismo una single page app de React que prerenderiza cada página pública al compilar, así que estas son las comprobaciones que hacemos en nuestras propias páginas. Pega el código fuente de una página en el comprobador para ver qué recibe un rastreador antes de que se ejecute nada de JavaScript.
Sí. Google renderiza JavaScript, pero las páginas esperan en una cola de renderizado y todo lo que no carga se pierde. Otros buscadores y los bots de vista previa de enlaces renderizan menos o nada, así que servir HTML es la opción más segura.
No. Next.js facilita el renderizado en el servidor y la generación estática, pero una SPA al estilo de Vite o Create React App puede prerenderizar sus rutas públicas al compilar y obtener el mismo HTML rastreable.
No para las etiquetas básicas. React 19 renderiza los elementos title, meta y link desde cualquier componente y los mueve al head. react-helmet-async sigue siendo útil en React 18 y versiones anteriores.
No cuando los rastreadores y las personas reciben el mismo contenido. El prerenderizado solo guarda la página que tus usuarios verían de todos modos. Se convierte en cloaking si el HTML que se sirve a los bots dice algo distinto.
Formas de dar HTML real a los rastreadores
React 19 permite que cualquier componente renderice etiquetas title, meta y link; React las mueve al head del documento. Cada ruta define las suyas.
Envuelve la app una vez en HelmetProvider y después define las etiquetas en cada página. La versión async es segura para el renderizado en el servidor y el prerenderizado.
Google ignora todo lo que va después de un # al decidir qué es una URL. Usa la History API (BrowserRouter, createBrowserRouter) para que cada vista tenga su propia ruta.
Los rastreadores siguen los elementos a con un href. Un manejador de clic en un div es invisible para ellos. Los componentes Link del router renderizan un enlace real.
Una app solo de cliente responde a cualquier URL con el estado 200, así que una página que no existe parece real. Añade un noindex a la vista de página no encontrada, o sirve un 404 real desde el servidor o desde el paso de prerenderizado.
Incluye cada URL pública una sola vez, con su dirección canónica. Genéralo a partir de la misma lista de rutas que usa tu app, para que nunca se desincronicen.
¿Necesitas que te escriban las etiquetas? Prueba el
Comprobador del código fuente
Pega el HTML de Ver código fuente de la página para comprobar qué recibe un rastreador.
Código fuente de la página (el ejemplo es el típico HTML vacío de una SPA)
Checklist de SEO para SPA
Título
"{title}" ({n} caracteres)
No hay título en el HTML
Meta descripción
{n} caracteres
Falta
Enlace canonical
Título principal (h1)
No hay h1 antes de que se ejecute JavaScript
Texto visible
{n} palabras en el body antes de que se ejecute JavaScript
Enlaces rastreables
{n} elementos a con un href real
Título Open Graph (vistas previas de enlaces)
Indexación permitida
meta robots: {robots}
Sin meta robots (indexable)
Empieza gratis · Sin tarjeta de crédito