SEO para frameworks de JavaScript

SEO para frameworks de JavaScript — React, Next.js, Vue, Nuxt, Angular, Svelte y Astro. Cómo el modo de renderizado (SSR, SSG, CSR) determina lo que Google puede indexar y qué frameworks gestionan mejor el SEO de fábrica.

Publicado por primera vez: 26 jun 2026 · Última actualización: 11 ago 2026 · Avanzado
Idiomas

El SEO para frameworks de JavaScript depende del modo de renderizado: SSG y SSR proporcionan a Googlebot HTML preconstruido; CSR requiere una ejecución de JavaScript que puede funcionar o fallar. Next.js y Nuxt ofrecen la mayor cantidad de soporte SEO integrado (SSR, SSG, ISR y API de metadatos). React y Vue puros en modo CSR son las opciones más arriesgadas para SEO. La arquitectura de islas de Astro es excelente para SEO de forma predeterminada. Angular requiere SSR mediante @angular/ssr (antes Angular Universal) para una indexación fiable.

TL;DR — En el nivel técnico, el SEO de los frameworks de JS consiste en: (1) la arquitectura de renderizado del payload HTML inicial, (2) la inyección de metadatos en <head> antes de enviar la respuesta, (3) cómo gestiona el framework la hidratación y el descubrimiento de enlaces, y (4) la antigüedad de la caché ISR. Next.js tiene las herramientas SEO integradas más completas (API de Metadata, app/sitemap.ts integrado y optimización de imágenes). Astro es el más seguro para SEO por su arquitectura.

Modo de renderizado, API de metadatos y compatibilidad con ISR por framework

Las capacidades y los valores predeterminados de los frameworks cambian con cada versión; verifícalos en la documentación oficial de cada uno. Evidence for this claim Primary standard or official documentation supporting the adjacent article claim. Scope: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confidence: high · Verified: web.dev: Rendering on the Web Ningún modo de renderizado garantiza la indexación ni el posicionamiento. Evidence for this claim Primary standard or official documentation supporting the adjacent article claim. Scope: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confidence: high · Verified: Google: JavaScript SEO basics Cuando compares frameworks para tomar una decisión, prueba las mismas rutas, el mismo contenido, el mismo destino de despliegue y las mismas herramientas para cada candidato: un benchmark que cambie cualquiera de esos elementos no mide el framework, sino la diferencia de configuración.

FrameworkRenderizado predeterminadoAPI de metadatos integradaCompatibilidad con SSR/SSGCompatibilidad SEO del ecosistema
AstroSSG (islas)Sí (<head> en archivos .astro, Content Collections para datos estructurados)AmbosFuerte
Next.jsSSR/SSG (configurable)Sí (API de Metadata en App Router)Ambos + ISRExcelente
NuxtSSR de forma predeterminadaSí (useHead, useSeoMeta)Ambos + ISRExcelente
SvelteKitSSR de forma predeterminadaSí (svelte:head)AmbosBuena
React Router (modo framework)SSR de forma predeterminadaSí (exportación meta)SSR + DeferredBuena
AngularCSR de forma predeterminadaMediante los servicios Meta/Title de AngularMediante @angular/ssrModerada
React (puro)CSRManual (react-helmet-async; react-helmet no recibe mantenimiento)Mediante Next.js/GatsbyDepende del wrapper
Vue (puro)CSRManual (@unhead/vue; vue-meta no recibe mantenimiento)Mediante NuxtDepende del wrapper

Remix v2 y React Router v7 se han fusionado: el renderizado del servidor y el modelo de carga de datos de Remix ahora se distribuyen como el «modo framework» de React Router, que es la ruta de actualización estable para las aplicaciones Remix v2. Remix 3 es una reescritura independiente y experimental sin React (beta), no el sucesor de Remix v2; no lo trates como una opción SSR lista para usar en una base de código React.

Tiempo de los metadatos, enlaces rastreables y antigüedad de la caché ISR

Momento de la inyección de metadatos — Los metadatos (<title>, <meta>) deben estar en la respuesta del servidor, no añadirse mediante JavaScript después de cargar la página. La API de Metadata de Next.js, useSeoMeta de Nuxt y el componente <head> de Astro lo gestionan correctamente. document.title = '...' o React Helmet en modo CSR no lo hacen: se ejecutan después de servir el HTML inicial.

Descubrimiento de enlaces — Googlebot descubre enlaces analizando el HTML. Es posible que no descubra los enlaces añadidos mediante JavaScript (onClick, enrutamiento dinámico sin etiquetas <a>). Usa elementos <a href> reales para la navegación importante.

Hidratación y contenido duplicado — Si SSR y CSR renderizan contenido diferente (un desajuste de hidratación), puedes acabar con contenido indexado que no coincide con lo que ven los usuarios. Comprueba si hay errores de hidratación en la consola del navegador.

Soft 404 — Los routers del lado del cliente pueden mostrar silenciosamente una interfaz de «página no encontrada» mientras devuelven un estado HTTP 200. Los motores de búsqueda las indexan como páginas reales. Asegúrate de que tu página 404 devuelva un estado 404 real y de que las redirecciones del lado del servidor devuelvan 301.

Invalidación de la caché ISR — En configuraciones ISR de Next.js y Nuxt, las páginas obsoletas pueden servirse a los rastreadores durante la ventana de revalidación. Establece un intervalo revalidate basado en el tiempo y, para el contenido que cambia según un calendario que no controlas (por ejemplo, al guardar en un CMS), combínalo con una revalidación bajo demanda activada desde un handler de ruta respaldado por un webhook. Consulta la guía de ISR de Next.js para ver la API completa.

// app/blog/[id]/page.tsx — time-based revalidation
export const revalidate = 3600 // re-check this page at most once an hour

// app/api/revalidate/route.ts — on-demand revalidation, called by a CMS webhook
import { revalidatePath } from 'next/cache'
import { NextRequest, NextResponse } from 'next/server'

export async function POST(request: NextRequest) {
  const { path, secret } = await request.json()
  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ message: 'Invalid secret' }, { status: 401 })
  }
  revalidatePath(path) // e.g. '/blog/1' — next request regenerates fresh HTML
  return NextResponse.json({ revalidated: true })
}

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.