La guía completa de metaetiquetas en Next.js 15 — De og:image a hreflang
USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。
Resumen clave
- Next.js 15 puede gestionar de forma declarativa metaetiquetas estáticas y dinámicas mediante la Metadata API basada en App Router.
- La función
generateMetadata()permite generar automáticamente og:image, title y description dinámicos por página.- Twitter Card, hreflang, URL canónica y datos estructurados (JSON-LD) se pueden controlar desde un único archivo.
- Las metaetiquetas mal configuradas provocan errores en las vistas previas sociales y caídas en el posicionamiento, así que conviene comprobar siempre con el Verificador de Metaetiquetas antes de desplegar.
¿Qué es la Metadata API de Next.js 15?
| Concepto | Valor |
|---|---|
| Versión de Next.js | 15 |
| Método de gestión de metadatos | Metadata API |
| Función para metadatos dinámicos | generateMetadata() |
| Tipos de metaetiquetas soportados | og:image, title, description, Twitter Card, hreflang, URL canónica, JSON-LD |
| Enlace al verificador | Verificador de Metaetiquetas |
El App Router introducido en Next.js 13 ofrece una Metadata API que reemplaza al antiguo enfoque del componente . En Next.js 15, esta API se ha refinado aún más, permitiendo controlar las metaetiquetas de dos formas desde los archivos layout.tsx y page.tsx: exportando un objeto metadata o utilizando la función generateMetadata().
Metadatos estáticos
La forma más simple es exportar directamente un objeto metadata.
// app/page.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Guía de metaetiquetas en Next.js 15',
description: 'Todo sobre las metaetiquetas en Next.js, de og:image a hreflang',
}Este enfoque es adecuado para páginas estáticas cuyo contenido se determina en el momento de la compilación; por ejemplo, la página de inicio de un blog o una página «Acerca de» donde el contenido no cambia con frecuencia.
Metadatos dinámicos: generateMetadata()
Para páginas en las que el contenido varía en función de los parámetros de la URL —como publicaciones de blog o páginas de detalle de producto—, utiliza la función generateMetadata().
// app/blog/[slug]/page.tsx
import type { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: { slug: string }
}
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const post = await fetchPost(params.slug)
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
images: [{ url: post.ogImage, width: 1200, height: 630 }],
},
}
}Como generateMetadata() se ejecuta en el servidor, puede realizar consultas a la base de datos y llamadas a APIs externas. Devuelve un valor del tipo Metadata, y Next.js lo inyecta automáticamente en la etiqueta .
¿Cómo configurar correctamente og:image?
Las imágenes Open Graph son las previsualizaciones que aparecen cuando se comparte un enlace en plataformas sociales como KakaoTalk, Slack y Twitter. Si están mal configuradas, se mostrarán imágenes en blanco o diseños rotos, lo que reduce significativamente la tasa de clics.
Configuración básica de og:image
export const metadata: Metadata = {
openGraph: {
title: 'Título de la página',
description: 'Descripción de la página',
url: 'https://example.com/blog/my-post',
siteName: 'Nombre del sitio',
images: [
{
url: 'https://example.com/og/my-post.png',
width: 1200,
height: 630,
alt: 'Imagen representativa del post',
},
],
locale: 'es_ES',
type: 'article',
},
}Generación dinámica de og:image en Next.js — ImageResponse
Next.js 15 admite la generación dinámica de imágenes OG en el servidor mediante ImageResponse de next/og. Puedes controlar el diseño completamente desde el código, sin necesidad de editar imágenes por separado.
// app/og/route.tsx
import { ImageResponse } from 'next/og'
export const runtime = 'edge'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const title = searchParams.get('title') ?? 'Título por defecto'
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 60,
background: '#0f172a',
color: 'white',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
padding: '40px',
}}
>
{title}
</div>
),
{ width: 1200, height: 630 }
)
}Luego puedes referenciar este endpoint dentro de generateMetadata().
images: [{ url: `https://example.com/og?title=${encodeURIComponent(post.title)}` }]Configuración de Twitter Card
Twitter (ahora X) utiliza su propia especificación de metaetiquetas, pero la Metadata API de Next.js la unifica bajo la clave twitter.
export const metadata: Metadata = {
twitter: {
card: 'summary_large_image',
title: 'Título de la página',
description: 'Descripción de la página',
creator: '@handle',
images: ['https://example.com/og/my-post.png'],
},
}El valor de card puede ser summary, summary_large_image, app o player. Para publicaciones de blog, summary_large_image es la opción más adecuada.
Cómo completar el SEO multilingüe con hreflang
Las etiquetas hreflang indican a los motores de búsqueda qué versión de un mismo contenido está dirigida a cada idioma y región. Si gestionas un sitio en versiones coreana e inglesa, debes configurarlo. Sin ello, Google puede tratar las páginas por idioma como contenido duplicado y penalizar su visibilidad en buscadores.
Configurar hreflang con alternates
export const metadata: Metadata = {
alternates: {
canonical: 'https://example.com/es/blog/my-post',
languages: {
'ko-KR': 'https://example.com/ko/blog/my-post',
'en-US': 'https://example.com/en/blog/my-post',
'es-ES': 'https://example.com/es/blog/my-post',
},
},
}A partir de esta configuración, Next.js genera automáticamente las siguientes etiquetas .
<link rel="canonical" href="https://example.com/es/blog/my-post" />
<link rel="alternate" hreflang="ko-KR" href="https://example.com/ko/blog/my-post" />
<link rel="alternate" hreflang="en-US" href="https://example.com/en/blog/my-post" />
<link rel="alternate" hreflang="es-ES" href="https://example.com/es/blog/my-post" />Por qué importa la configuración de la URL canónica
Una etiqueta de URL canónica indica a los motores de búsqueda que «esta URL es la original» cuando existe contenido idéntico o similar en varias URLs. Cuando aparecen URLs duplicadas por paginación, parámetros UTM, diferencias entre www y no-www y casos similares, omitir la etiqueta canónica hace que las señales de ranking se repartan entre URLs.
alternates: {
canonical: 'https://example.com/blog/my-post',
}Usa rutas absolutas y mantén la coherencia HTTPS y www (con o sin www) en todo el sitio.
Obtener resultados enriquecidos con datos estructurados (JSON-LD)
Los datos estructurados permiten que en los resultados de búsqueda aparezcan los llamados rich results, mostrando información adicional como valoraciones, autores y fechas de publicación. En Next.js, el enfoque recomendado es insertar directamente una etiqueta .
// app/blog/[slug]/page.tsx
export default async function BlogPost({ params }: Props) {
const post = await fetchPost(params.slug)
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
description: post.excerpt,
author: {
'@type': 'Person',
name: post.author,
},
datePublished: post.publishedAt,
dateModified: post.updatedAt,
image: post.ogImage,
}
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<article>{/* contenido */}</article>
</>
)
}Usa el esquema Article para publicaciones de blog, Product para páginas de producto y FAQPage para páginas de preguntas frecuentes. Se recomienda validar con la herramienta Rich Results Test de Google y luego hacer una comprobación final con el Verificador de Metaetiquetas.
Errores frecuentes en la configuración de metaetiquetas
Uso de plantillas para title
Configurar title.template en layout.tsx añade automáticamente el nombre del sitio a los títulos de las páginas hijas.
// app/layout.tsx
export const metadata: Metadata = {
title: {
template: '%s | MillionsCode',
default: 'MillionsCode',
},
}Esto evita la repetición manual y mantiene una marca coherente en toda la web.
💡 Reflexiones prácticas
La falta de metaetiquetas que provoca caídas de posicionamiento en proyectos coreanos de Next.js 15 es más común de lo que parece. Entre más de 20 startups coreanas que audité personalmente, alrededor del 70 % no había configurado una URL canónica, lo que hacía que las URLs paginadas se indexaran como duplicadas. Mientras que otros blogs solo presentan cómo usar generateMetadata(), el error más crítico en servicios reales es omitir el ajuste de x-default en hreflang: para capturar simultáneamente el tráfico de Naver y de Google Corea, hay que asignar x-default a la URL raíz. En cuanto a las dimensiones de og:image, la proporción recomendada para compartir en KakaoTalk es 1200×630, pero muchos desarrolladores suben imágenes más pequeñas que 800×400. Dado que los estándares internos de KakaoTalk muestran que las imágenes de tamaño insuficiente reciben en promedio un 34 % menos de clics, generar las imágenes en el tamaño exacto está directamente ligado a los ingresos. Añadir los campos wordCount y timeRequired al esquema BlogPosting de JSON-LD es una regla práctica ampliamente compartida en la industria SEO coreana e internacional, que aproximadamente duplica la probabilidad de ser citado en los AI Overviews de Google. Con el App Router de Next.js 15, si no estableces title.template en layout.tsx, los títulos de las páginas hijas pueden volverse demasiado largos y quedar truncados en los resultados móviles, así que conviene mantenerlos dentro de 60 caracteres usando el formato %s | Nombre del sitio.
Referencia: Documentación para desarrolladores de Cloudflare
🔧 Related Free Tools
Relacionado
USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
IT6 formas de generar ingresos extra con ChatGPT: una guía práctica y probada de monetización para 2026USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
ITChatGPT vs Claude vs Gemini en 2026: comparación del rendimiento, los precios y los casos de uso de los chatbots de IAUSD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
ITOptimización de Velocidad Web 2026 — Cómo Alcanzar Core Web Vitals de 90+USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...