Saltar al contenido
Neaptideestudio
blog

Checklist SEO para Next.js App Router: visibilidad SSR, canonicals, hreflang y crawlers de IA

Neaptide · 30 de octubre de 2026 · 8 min de lectura

Compruebe qué entrega realmente Next.js App Router en el HTML inicial: encabezados SSR visibles sin opacity:0, herencia de alternates, enlaces de idioma y redirecciones.

En este artículo
Checklist SEO para Next.js App Router — 1 SSR HTML (<h1> visible) · 2 Alternates (6 hreflang + RSS) · 3 Enlaces HTML (<a hreflang>) · 4 Schema (JSON-LD + sitemap).

Un sitio en Next.js App Router puede verse perfecto en el navegador y, al mismo tiempo, entregar el título <h1> oculto con style="opacity:0" en el HTML inicial, perder etiquetas <link rel="alternate"> al sobrescribir metadatos en rutas hijas o esconder el selector de idioma dentro de botones sin href. Audite siempre la respuesta HTTP y el HTML renderizado en servidor antes de dar por buena una publicación.

Aunque los Server Components renderizan HTML en el servidor por defecto, los contenedores de animación en cliente, generateMetadata() y middleware.ts determinan lo que reciben Googlebot y los rastreadores de IA (GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot). A continuación documentamos cinco fallos reales corregidos en la web multilingüe en Next.js 15 de Neaptide y una lista de verificación repetible.

¿Qué detectó y corrigió nuestra auditoría sobre Next.js 15 en Neaptide?

En octubre de 2026 revisamos el HTML servido, las cabeceras HTTP, los metadatos y el sitemap en los seis idiomas de Neaptide. La tabla recoge los cinco defectos técnicos detectados y el resultado verificado tras el despliegue.

Cinco comprobaciones SEO de Next.js App Router en la auditoría de producción de Neaptide
Capa revisadaDefecto en el HTML SSR inicialCorrección aplicada y resultado verificado
Componentes de animación Reveal.tsx y Hero.tsxEl <h1>, la introducción y las tarjetas se servían con style="opacity:0;transform:translateY(12px)" hasta la hidratación (~1,2 s)Se eliminó opacity:0 del estado SSR inicial; títulos y textos quedan visibles desde el primer byte
Helper generateMetadata() en lib/meta.tsEl objeto alternates: { canonical, languages } de las páginas sobrescribía el layout y eliminaba <link rel="alternate" type="application/rss+xml">Se añadió types: { "application/rss+xml": "https://www.neaptide.ai/feed.xml" } en pageMetadata()
Selector de idioma components/LangSwitcher.tsxLos idiomas solo se montaban al hacer clic mediante elementos <button> sin atributo hrefLos 6 idiomas se renderizan en el DOM SSR como enlaces <a href={...} hrefLang={l} lang={l}>
Redirección raíz (/) en middleware.tsLos bots que pedían / sin cabeceras geo ni Accept-Language no recibían una cabecera Vary explícitaRedirección determinista a x-default (/en) con Vary: Accept-Language, Cookie, x-vercel-ip-country, cf-ipcountry
Datos estructurados lib/schema.ts y app/sitemap.tsTres páginas de servicio fijaban areaServed: United States; el sitemap omitía imágenes de casos y artículosSe alineó areaServed y se añadieron portadas y gráficos localizados en sitemap.xml

Estas observaciones describen mejoras técnicas verificadas en nuestro propio código. Corregirlas elimina barreras de renderizado e indexación; el posicionamiento orgánico y las citas en motores de IA siguen dependiendo de la competencia y de la autoridad del sitio.

¿Por qué style="opacity:0" en las animaciones perjudica el LCP y el rastreo?

Muchos sitios en Next.js envuelven sus encabezados y bloques principales en componentes de aparición o Framer Motion con estado inicial opacity: 0. Como Next.js pre-renderiza los Client Components en el servidor usando ese estado inicial, el HTML llega con style="opacity:0" en el <h1> y en el texto principal.

Esto retrasa el cálculo de Largest Contentful Paint (LCP) hasta que finaliza la hidratación de JavaScript y presenta el contenido principal como oculto ante los rastreadores que leen el HTML sin ejecutar scripts. Mantenga el texto visible en el SSR usando solo una traslación suave (transform: translateY(12px)) sin opacity: 0.

¿Cómo puede generateMetadata borrar las etiquetas alternates del layout?

En Next.js App Router, la combinación de metadatos entre layout y página es superficial. Si una página devuelve su propio objeto alternates con canonical y languages, reemplaza por completo el objeto alternates del layout padre.

Centralice canonical, languages (incluido x-default) y types (como el feed RSS) en una única función compartida:

export function pageMetadata(locale: Locale, opts: PageMetaInput): Metadata {
  const canonicalUrl = `${SITE.url}${localeHref(locale, opts.path)}`;
  const languages: Record<string, string> = {};
  for (const l of LOCALES) {
    languages[l] = `${SITE.url}${localeHref(l, opts.path)}`;
  }
  languages["x-default"] = `${SITE.url}${localeHref(X_DEFAULT_LOCALE, opts.path)}`;

  return {
    alternates: {
      canonical: canonicalUrl,
      languages,
      types: {
        "application/rss+xml": `${SITE.url}/feed.xml`,
      },
    },
  };
}

¿Por qué el selector de idioma y la redirección raíz deben ser explícitos para los bots?

Un selector de idioma que solo monta sus opciones al hacer clic o usa botones <button> no deja enlaces HTML rastreables entre idiomas. Renderizar enlaces <a href="/en/..." hrefLang="en" lang="en"> en el DOM de la cabecera refuerza el descubrimiento interno en todas las páginas.

Compruebe también qué ocurre cuando un bot solicita / sin cookies ni cabecera Accept-Language: el middleware debe redirigir de forma determinista al idioma x-default (/en) e incluir la cabecera Vary adecuada.

Cómo verificar un despliegue en Next.js App Router en seis pasos

Ejecute estas seis comprobaciones antes de aprobar un lanzamiento:

  1. Visibilidad en el HTML SSR: descargue la página con curl -s y confirme que el único <h1> y el texto principal aparecen sin style="opacity:0".
  2. Paridad de canonical y hreflang: verifique que cada URL localizada incluye su canonical autorreferencial, los 6 idiomas, x-default y el enlace RSS.
  3. Enlaces rastreables: confirme que el menú, el pie de página y el selector de idioma usan etiquetas <a href="..."> en el HTML inicial.
  4. Redirección raíz: pruebe / con curl -I y una cabecera Accept-Language vacía para confirmar un único salto permanente al destino previsto.
  5. Coherencia de JSON-LD: compruebe que WebPage, Service, Article, BreadcrumbList y FAQPage coinciden con el texto visible y el idioma de la página.
  6. Cobertura en sitemap.xml y llms.txt: verifique que todas las rutas e imágenes clave estén incluidas en /sitemap.xml y /llms.txt.
curl -s https://www.neaptide.ai/en | grep -E '<h1|rel="canonical"|hrefLang|application/rss\+xml'
curl -I -H 'Accept-Language:' https://www.neaptide.ai/

Si necesita una revisión técnica de su sitio o plataforma en Next.js, en Neaptide realizamos auditorías SEO y GEO con pruebas HTTP reproducibles y tareas listas para desarrollo.

faq

Lo esencial en breve

¿Usar Server Components en Next.js garantiza un buen SEO técnico?

No. Las animaciones en cliente con opacity:0, los objetos generateMetadata() incompletos, los menús con <button> y las redirecciones en middleware aún pueden ocultar contenido o romper canonical y hreflang.

¿Por qué es un problema style="opacity:0" en el SSR si JavaScript muestra el texto después?

Retrasa el Largest Contentful Paint (LCP) hasta que termina la hidratación y marca los encabezados como invisibles para los bots que procesan el HTML inicial sin ejecutar JavaScript.

¿Por qué desaparece el enlace RSS del layout en las páginas interiores?

Porque Next.js fusiona los metadatos de forma superficial: cuando una página define alternates, reemplaza todo el objeto alternates del layout padre si no se incluye alternates.types en el helper común.

¿Son necesarios los enlaces <a hreflang> en el menú si ya están en <head>?

Sí. Los enlaces <a href="..." hrefLang="..."> en el DOM permiten a los rastreadores navegar directamente entre las versiones de idioma desde cualquier página.

¿Qué debe devolver la ruta raíz / a un rastreador sin cabecera de idioma?

Una redirección determinista hacia el idioma x-default (por ejemplo, /en) acompañada de la cabecera Vary con Accept-Language, Cookie y las cabeceras geográficas.

¿Qué incluye la auditoría SEO para Next.js de Neaptide?

Revisamos el HTML SSR, el LCP, la matriz de canonical y hreflang, los datos estructurados JSON-LD, el sitemap y el acceso de bots de IA, entregando incidencias priorizadas por archivo.