IT

La guía completa de metaetiquetas en Next.js 15 — De og:image a hreflang

USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。

La guía completa de metaetiquetas en Next.js 15 — De og:image a hreflang

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?

large gray ship sitting next body water
ConceptoValor
Versión de Next.js15
Método de gestión de metadatosMetadata API
Función para metadatos dinámicosgenerateMetadata()
Tipos de metaetiquetas soportadosog:image, title, description, Twitter Card, hreflang, URL canónica, JSON-LD
Enlace al verificadorVerificador 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.

tsx
// 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().

tsx
// 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?

fighter jet sitting on aircraft carrier

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

tsx
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.

tsx
// 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().

tsx
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.

tsx
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

tsx
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 .

html
<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.

tsx
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

🔧 Related Free Tools

Relacionado