SEO técnico en el Next.js App Router: metadatos, mapas del sitio y JSON-LD
Aprenda cómo los ayudantes de metadatos compartidos, las configuraciones predeterminadas del diseño raíz, robots.ts, un mapa del sitio dinámico, JSON-LD preciso y las auditorías de páginas proporcionan a una aplicación Next.js una base SEO impecable.
Fuentes: How I Got a Next.js Project to 100% SEO on Lighthouse
Una aplicación Next.js puede parecer terminada y, aun así, resultar difícil de leer para los motores de búsqueda: las páginas carecen de URLs canónicas, no están definidas las reglas para los rastreadores, y el contenido nuevo nunca llega al mapa del sitio. Esta guía sigue a un sitio con API de datos ficticios que cuenta con muchas páginas de recursos, desde su primera auditoría SEO con Lighthouse hasta alcanzar una puntuación de 100, mostrando los siete cambios realizados con las API de metadatos integradas del App Router.
Generar metadatos de página a partir de una función auxiliar
Escribir los metadatos manualmente en cada página provoca desviaciones, como la falta de una URL canónica aquí o un título Open Graph obsoleto allá. Una pequeña función auxiliar soluciona esto: cada página solo envía su título, descripción, ruta y una bandera opcional noIndex, y la función auxiliar los expande en campos canónicos, para robots y Open Graph:
export function createPageMetadata({
title,
description,
path,
noIndex = false,
}: PageMetadata) {
return {
title,
description,
alternates: {
canonical: path,
},
robots: noIndex ? "noindex, nofollow" : "index, follow",
openGraph: {
title,
description,
url: path,
type: "website",
},
};
}
La indexación es opcional: una bandera convierte una página en noindex, nofollow. Dado que path es relativo, la herramienta depende de una URL base definida en el layout raíz.
Coloque los valores predeterminados para todo el sitio en el layout raíz
Todo lo que se comparte en todo el sitio debe incluirse en la exportación de metadata de layout.tsx:
metadataBase- un modelo de título
- una descripción predeterminada
- valores predeterminados para Open Graph
- configuraciones de la tarjeta de Twitter
- valores predeterminados para robots
- el atributo
langen el elemento<html>
Una versión simplificada de esa exportación se ve así:
export const metadata: Metadata = {
metadataBase: new URL("https://mockdata.ir"),
title: {
default: "MockData",
template: "%s | MockData",
},
description: "...",
};
Con la plantilla %s | MockData, una página titulada “Users API” se muestra como “Users API | MockData”, mientras que las páginas sin título utilizan el valor default. metadataBase es lo que convierte los valores relativos canonical y de Open Graph url del helper en URLs absolutas. Tenga en cuenta que lang no es un campo de metadatos; úselo en la etiqueta <html> que muestra el layout.
Defina reglas para los rastreadores con robots.ts
En lugar de dejar las reglas para los rastreadores sin definir, genere un archivo robots.txt a partir de un archivo app/robots.ts que devuelva un objeto MetadataRoute.Robots de tipo especificado:
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: "*",
allow: "/",
},
sitemap: "https://mockdata.ir/sitemap.xml",
};
}
Está diseñado deliberadamente de forma minimalista: todos los agentes de usuario pueden rastrear todo, y se indica la ubicación del mapa del sitio.
Genere el mapa del sitio a partir de sus datos
Con páginas de recursos para usuarios, publicaciones, productos y más, un mapa del sitio XML mantenido manualmente no es escalable. La exportación por defecto de sitemap.ts puede ser async, lo que le permite consultar la misma fuente que utilizan las páginas:
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const resources = await getPublicResources();
return [
{
url: "https://mockdata.ir",
lastModified: new Date(),
},
...resources.map((resource) => ({
url: `https://mockdata.ir/${resource.slug}`,
lastModified: resource.updatedAt,
})),
];
}
Cada recurso se asocia a una URL donde updatedAt funciona como lastModified, de modo que los nuevos recursos públicos se integran automáticamente en el mapa del sitio. Una mejora: new Date() para la página principal indica un cambio en cada generación; un timestamp real del contenido es más preciso.
Agregue datos estructurados solo cuando sea necesario
JSON-LD con el vocabulario de Schema.org indica a los motores de búsqueda qué representa una página. La propia aplicación se describe como SoftwareApplication, y los tipos utilizados son:
WebSiteOrganizationSoftwareApplication
BreadcrumbListBusque la precisión, no la cantidad: el marcado debe describir el contenido que realmente se encuentra en la página. Las reseñas inventadas, las calificaciones u otras propiedades fabricadas son engañosas y pueden violar las pautas de los motores de búsqueda.
Mantenga coherentes las pistas de navegación entre la interfaz de usuario y el esquema
Las páginas de documentación anidadas muestran una ruta visible como Inicio → Documentos → API de usuarios, y la misma jerarquía se emite como datos estructurados BreadcrumbList. La ruta visible y el marcado deben describir siempre la misma estructura.
Haga una auditoría manual de cada página indexable
Finalmente, revise cada página pública por separado:
- ¿Tiene exactamente un H1 claro?
- ¿El título describe esta página específica?
- ¿La descripción coincide con el contenido real?
- ¿Existen enlaces internos útiles hacia y desde ella?
- ¿Debería esta página ser indexada en absoluto?
- ¿Hay alguna página vacía o de bajo valor expuesta a los rastreadores?
No toda ruta debe aparecer en los resultados de búsqueda; a menudo noindex es la opción adecuada. Para conocer más sobre la estructura de encabezados, consulte esta guía sobre HTML semántico en lo que respecta a la marcación.
Qué significa y qué no significa una puntuación perfecta en Lighthouse SEO
Después de aplicar estas correcciones, Lighthouse indicó una puntuación SEO de 100. Esa cifra verifica aspectos técnicos básicos como títulos, descripciones y capacidad de rastreo; no dice nada sobre el posicionamiento. El posicionamiento depende de la calidad del contenido, la intención de búsqueda, la autoridad, los enlaces de retroceso, la competencia, el rendimiento y muchos otros factores.
El verdadero valor radica en la base sólida que se crea. Realizar la auditoría antes de publicar cualquier aplicación Next.js es económico y permite detectar muchos errores menores.
Puntos clave
- Centralice los metadatos por página en una función auxiliar y establezca valores predeterminados compartidos, incluyendo
metadataBase, en el diseño raíz. - Utilice
robots.tsy unsitemap.tsasíncrono para que las reglas de los rastreadores y las URLs estén sincronizadas con sus datos. - Agregue solo datos estructurados que describan fielmente la página, y mantenga los breadcrumbs idénticos tanto en la interfaz de usuario como en el esquema.
- Considere
noindexcomo una opción legítima para páginas que no deben aparecer en los resultados de búsqueda. - Interprete una puntuación de Lighthouse de 100 como “técnicamente sólida”, y no como una garantía de clasificación.
Lecturas relacionadas
- Migrar de next/router: Params, URLs Shallow y 404s en App Router — Descubre cómo funcionan params, useParams, las actualizaciones de URLs Shallow, la navegación programática y las páginas 404 reales en el App Router de Next.js una vez que next/router ya no esté disponible.
- Dónde dibujar la línea servidor-cliente en una página App Router de Next.js — Un modelo mental práctico para los Componentes del Servidor de React: qué se ejecuta dónde, cómo se divide una página de artículo en partes del servidor y del cliente, y las reglas de importación a seguir.