Objeto Metadata y opciones de generateMetadata
Esta página cubre todas las opciones de Metadata basada en configuración con generateMetadata
y el objeto metadata estático.
import { Metadata } from 'next'
// metadata estática
export const metadata: Metadata = {
title: '...',
}
// o metadata dinámica
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
// metadata estática
export const metadata = {
title: '...',
}
// o metadata dinámica
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
Es bueno saber:
- El objeto
metadata
y la funcióngenerateMetadata
solo son compatibles en Componentes de Servidor.- No puede exportar tanto el objeto
metadata
como la funcióngenerateMetadata
desde el mismo segmento de ruta.
El objeto metadata
Para definir metadata estática, exporte un objeto Metadata
desde un archivo layout.js
o page.js
.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}
export const metadata = {
title: '...',
description: '...',
}
export default function Page() {}
Consulte los Campos de Metadata para una lista completa de opciones compatibles.
Función generateMetadata
La metadata dinámica que depende de información dinámica, como parámetros de ruta actuales, datos externos o metadata
en segmentos padres, puede configurarse exportando una función generateMetadata
que devuelve un objeto Metadata
.
import { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// leer parámetros de ruta
const id = params.id
// obtener datos
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// opcionalmente acceder y extender (en lugar de reemplazar) metadata padre
const previousImages = (await parent).openGraph?.images || []
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
export default function Page({ params, searchParams }: Props) {}
export async function generateMetadata({ params, searchParams }, parent) {
// leer parámetros de ruta
const id = params.id
// obtener datos
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// opcionalmente acceder y extender (en lugar de reemplazar) metadata padre
const previousImages = (await parent).openGraph?.images || []
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
export default function Page({ params, searchParams }) {}
Parámetros
La función generateMetadata
acepta los siguientes parámetros:
-
props
- Un objeto que contiene los parámetros de la ruta actual:-
params
- Un objeto que contiene los parámetros de ruta dinámica desde el segmento raíz hasta el segmento donde se llama agenerateMetadata
. Ejemplos:Ruta URL params
app/shop/[slug]/page.js
/shop/1
{ slug: '1' }
app/shop/[tag]/[item]/page.js
/shop/1/2
{ tag: '1', item: '2' }
app/shop/[...slug]/page.js
/shop/1/2
{ slug: ['1', '2'] }
-
searchParams
- Un objeto que contiene los parámetros de búsqueda de la URL actual. Ejemplos:URL searchParams
/shop?a=1
{ a: '1' }
/shop?a=1&b=2
{ a: '1', b: '2' }
/shop?a=1&a=2
{ a: ['1', '2'] }
-
-
parent
- Una promesa de la metadata resuelta de segmentos de ruta padres.
Devuelve
generateMetadata
debe devolver un objeto Metadata
que contenga uno o más campos de metadata.
Es bueno saber:
- Si la metadata no depende de información en tiempo de ejecución, debe definirse usando el objeto
metadata
estático en lugar degenerateMetadata
.- Las solicitudes
fetch
se memorizan automáticamente para los mismos datos engenerateMetadata
,generateStaticParams
, Layouts, Pages y Componentes de Servidor. Se puede usarcache
de React sifetch
no está disponible.searchParams
solo está disponible en segmentospage.js
.- Los métodos
redirect()
ynotFound()
de Next.js también pueden usarse dentro degenerateMetadata
.
Campos de Metadata
title
El atributo title
se usa para establecer el título del documento. Puede definirse como una cadena simple o un objeto plantilla opcional.
String
export const metadata = {
title: 'Next.js',
}
<title>Next.js</title>
Template object
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '...',
default: '...',
absolute: '...',
},
}
export const metadata = {
title: {
default: '...',
template: '...',
absolute: '...',
},
}
Default
title.default
puede usarse para proporcionar un título de respaldo a segmentos de ruta hijos que no definen un title
.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
default: 'Acme',
},
}
import type { Metadata } from 'next'
export const metadata: Metadata = {}
// Salida: <title>Acme</title>
Template
title.template
puede usarse para añadir un prefijo o sufijo a titles
definidos en segmentos de ruta hijos.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // se requiere un valor default al crear una plantilla
},
}
export const metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // se requiere un valor default al crear una plantilla
},
}
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About',
}
// Salida: <title>About | Acme</title>
export const metadata = {
title: 'About',
}
// Salida: <title>About | Acme</title>
Es bueno saber:
title.template
se aplica a segmentos de ruta hijos y no al segmento donde se define. Esto significa:
title.default
es requerido cuando se añade untitle.template
.title.template
definido enlayout.js
no se aplicará a untitle
definido en unpage.js
del mismo segmento de ruta.title.template
definido enpage.js
no tiene efecto porque una página siempre es el segmento terminal (no tiene segmentos de ruta hijos).
title.template
no tiene efecto si una ruta no ha definido untitle
otitle.default
.
Absolute
title.absolute
puede usarse para proporcionar un título que ignore title.template
establecido en segmentos padres.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
},
}
export const metadata = {
title: {
template: '%s | Acme',
},
}
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
absolute: 'About',
},
}
// Salida: <title>About</title>
export const metadata = {
title: {
absolute: 'About',
},
}
// Salida: <title>About</title>
Es bueno saber:
layout.js
title
(string) ytitle.default
definen el título predeterminado para segmentos hijos (que no definen su propiotitle
). Aumentarátitle.template
del segmento padre más cercano si existe.title.absolute
define el título predeterminado para segmentos hijos. Ignoratitle.template
de segmentos padres.title.template
define una nueva plantilla de título para segmentos hijos.
page.js
- Si una página no define su propio título, se usará el título resuelto del padre más cercano.
title
(string) define el título de la ruta. Aumentarátitle.template
del segmento padre más cercano si existe.title.absolute
define el título de la ruta. Ignoratitle.template
de segmentos padres.title.template
no tiene efecto enpage.js
porque una página siempre es el segmento terminal de una ruta.
description
export const metadata = {
description: 'The React Framework for the Web',
}
<meta name="description" content="The React Framework for the Web" />
Campos básicos
export const metadata = {
generator: 'Next.js',
applicationName: 'Next.js',
referrer: 'origin-when-cross-origin',
keywords: ['Next.js', 'React', 'JavaScript'],
authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
colorScheme: 'dark',
creator: 'Jiachi Liu',
publisher: 'Sebastian Markbåge',
formatDetection: {
email: false,
address: false,
telephone: false,
},
}
<meta name="application-name" content="Next.js" />
<meta name="author" content="Seb" />
<link rel="author" href="https://nextjs.org" />
<meta name="author" content="Josh" />
<meta name="generator" content="Next.js" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="referrer" content="origin-when-cross-origin" />
<meta name="color-scheme" content="dark" />
<meta name="creator" content="Jiachi Liu" />
<meta name="publisher" content="Sebastian Markbåge" />
<meta name="format-detection" content="telephone=no, address=no, email=no" />
metadataBase
metadataBase
es una opción conveniente para establecer un prefijo de URL base para campos metadata
que requieren una URL completa.
metadataBase
permite que los camposmetadata
basados en URL definidos en el segmento de ruta actual y por debajo usen una ruta relativa en lugar de una URL absoluta que de otro modo sería requerida.- La ruta relativa del campo se combinará con
metadataBase
para formar una URL completa. - Si no se configura,
metadataBase
se rellena automáticamente con un valor predeterminado.
export const metadata = {
metadataBase: new URL('https://acme.com'),
alternates: {
canonical: '/',
languages: {
'en-US': '/en-US',
'de-DE': '/de-DE',
},
},
openGraph: {
images: '/og-image.png',
},
}
<link rel="canonical" href="https://acme.com" />
<link rel="alternate" hreflang="en-US" href="https://acme.com/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://acme.com/de-DE" />
<meta property="og:image" content="https://acme.com/og-image.png" />
Es bueno saber:
metadataBase
normalmente se establece en elapp/layout.js
raíz para aplicarse a camposmetadata
basados en URL en todas las rutas.- Todos los campos
metadata
basados en URL que requieren URLs absolutas pueden configurarse con una opciónmetadataBase
.metadataBase
puede contener un subdominio, por ejemplo,https://app.acme.com
o una ruta base, por ejemplo,https://acme.com/start/from/here
.- Si un campo
metadata
proporciona una URL absoluta,metadataBase
se ignorará.- Usar una ruta relativa en un campo
metadata
basado en URL sin configurar unmetadataBase
causará un error de compilación.- Next.js normalizará barras duplicadas entre
metadataBase
(por ejemplo,https://acme.com/
) y un campo relativo (por ejemplo,/path
) a una sola barra (por ejemplo,https://acme.com/path
).
Valor predeterminado
Si no se configura, metadataBase
tiene un valor predeterminado:
- Cuando se detecta
VERCEL_URL
:https://${process.env.VERCEL_URL}
, de lo contrario, recurre ahttp://localhost:${process.env.PORT || 3000}
. - Al sobrescribir el valor predeterminado, recomendamos usar variables de entorno para calcular la URL. Esto permite configurar una URL para entornos de desarrollo local, staging y producción.
Composición de URL
La composición de URL favorece la intención del desarrollador sobre la semántica predeterminada de recorrido de directorios.
- Las barras diagonales finales entre
metadataBase
y camposmetadata
se normalizan. - Una ruta "absoluta" en un campo
metadata
(que normalmente reemplazaría toda la ruta de la URL) se trata como una ruta "relativa" (comenzando desde el final demetadataBase
).
Por ejemplo, dado el siguiente metadataBase
:
import { Metadata } from 'next'
export const metadata: Metadata = {
metadataBase: new URL('https://acme.com'),
}
export const metadata = {
metadataBase: new URL('https://acme.com'),
}
Cualquier campo metadata
que herede el metadataBase
anterior y establezca su propio valor se resolverá de la siguiente manera:
Campo metadata | URL resuelta |
---|---|
/ | https://acme.com |
./ | https://acme.com |
payments | https://acme.com/payments |
/payments | https://acme.com/payments |
./payments | https://acme.com/payments |
../payments | https://acme.com/payments |
https://beta.acme.com/payments | https://beta.acme.com/payments |
openGraph
export const metadata = {
openGraph: {
title: 'Next.js',
description: 'The React Framework for the Web',
url: 'https://nextjs.org',
siteName: 'Next.js',
images: [
{
url: 'https://nextjs.org/og.png',
width: 800,
height: 600,
},
{
url: 'https://nextjs.org/og-alt.png',
width: 1800,
height: 1600,
alt: 'Mi texto alternativo personalizado',
},
],
locale: 'en_US',
type: 'website',
},
}
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image:url" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image:url" content="https://nextjs.org/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="Mi texto alternativo personalizado" />
<meta property="og:type" content="website" />
export const metadata = {
openGraph: {
title: 'Next.js',
description: 'The React Framework for the Web',
type: 'article',
publishedTime: '2023-01-01T00:00:00.000Z',
authors: ['Seb', 'Josh'],
},
}
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-01-01T00:00:00.000Z" />
<meta property="article:author" content="Seb" />
<meta property="article:author" content="Josh" />
Nota importante:
- Puede ser más conveniente usar la API de Metadatos basada en archivos para imágenes de Open Graph. En lugar de tener que sincronizar la exportación de configuración con archivos reales, la API basada en archivos generará automáticamente los metadatos correctos.
robots
import type { Metadata } from 'next'
export const metadata: Metadata = {
robots: {
index: false,
follow: true,
nocache: true,
googleBot: {
index: true,
follow: false,
noimageindex: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
}
<meta name="robots" content="noindex, follow, nocache" />
<meta
name="googlebot"
content="index, nofollow, noimageindex, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>
icons
Nota importante: Recomendamos usar la API de Metadatos basada en archivos para iconos siempre que sea posible. En lugar de tener que sincronizar la exportación de configuración con archivos reales, la API basada en archivos generará automáticamente los metadatos correctos.
export const metadata = {
icons: {
icon: '/icon.png',
shortcut: '/shortcut-icon.png',
apple: '/apple-icon.png',
other: {
rel: 'apple-touch-icon-precomposed',
url: '/apple-touch-icon-precomposed.png',
},
},
}
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
rel="apple-touch-icon-precomposed"
href="/apple-touch-icon-precomposed.png"
/>
export const metadata = {
icons: {
icon: [{ url: '/icon.png' }, new URL('/icon.png', 'https://example.com')],
shortcut: ['/shortcut-icon.png'],
apple: [
{ url: '/apple-icon.png' },
{ url: '/apple-icon-x3.png', sizes: '180x180', type: 'image/png' },
],
other: [
{
rel: 'apple-touch-icon-precomposed',
url: '/apple-touch-icon-precomposed.png',
},
],
},
}
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
rel="apple-touch-icon-precomposed"
href="/apple-touch-icon-precomposed.png"
/>
<link rel="icon" href="https://example.com/icon.png" />
<link
rel="apple-touch-icon"
href="/apple-icon-x3.png"
sizes="180x180"
type="image/png"
/>
Nota importante: Las etiquetas meta
msapplication-*
ya no son compatibles en las versiones Chromium de Microsoft Edge, por lo que ya no son necesarias.
themeColor
Más información sobre theme-color.
Color de tema simple
export const metadata = {
themeColor: 'black',
}
<meta name="theme-color" content="black" />
Con atributo media
export const metadata = {
themeColor: [
{ media: '(prefers-color-scheme: light)', color: 'cyan' },
{ media: '(prefers-color-scheme: dark)', color: 'black' },
],
}
<meta name="theme-color" media="(prefers-color-scheme: light)" content="cyan" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />
manifest
Un manifiesto de aplicación web, como se define en la especificación de Manifiesto de Aplicación Web.
export const metadata = {
manifest: 'https://nextjs.org/manifest.json',
}
<link rel="manifest" href="https://nextjs.org/manifest.json" />
twitter
Más información sobre la referencia de marcado de Twitter Card.
export const metadata = {
twitter: {
card: 'summary_large_image',
title: 'Next.js',
description: 'The React Framework for the Web',
siteId: '1467726470533754880',
creator: '@nextjs',
creatorId: '1467726470533754880',
images: ['https://nextjs.org/og.png'],
},
}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="The React Framework for the Web" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
export const metadata = {
twitter: {
card: 'app',
title: 'Next.js',
description: 'The React Framework for the Web',
siteId: '1467726470533754880',
creator: '@nextjs',
creatorId: '1467726470533754880',
images: {
url: 'https://nextjs.org/og.png',
alt: 'Next.js Logo',
},
app: {
name: 'twitter_app',
id: {
iphone: 'twitter_app://iphone',
ipad: 'twitter_app://ipad',
googleplay: 'twitter_app://googleplay',
},
url: {
iphone: 'https://iphone_url',
ipad: 'https://ipad_url',
},
},
},
}
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="The React Framework for the Web" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="Next.js Logo" />
<meta name="twitter:app:name:iphone" content="twitter_app" />
<meta name="twitter:app:id:iphone" content="twitter_app://iphone" />
<meta name="twitter:app:id:ipad" content="twitter_app://ipad" />
<meta name="twitter:app:id:googleplay" content="twitter_app://googleplay" />
<meta name="twitter:app:url:iphone" content="https://iphone_url" />
<meta name="twitter:app:url:ipad" content="https://ipad_url" />
<meta name="twitter:app:name:ipad" content="twitter_app" />
<meta name="twitter:app:name:googleplay" content="twitter_app" />
viewport
Nota importante: La etiqueta meta
viewport
se establece automáticamente con los siguientes valores predeterminados. Por lo general, no es necesaria una configuración manual ya que los valores predeterminados son suficientes. Sin embargo, se proporciona la información para completitud.
export const metadata = {
viewport: {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
},
}
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1"
/>
verification
export const metadata = {
verification: {
google: 'google',
yandex: 'yandex',
yahoo: 'yahoo',
other: {
me: ['my-email', 'my-link'],
},
},
}
<meta name="google-site-verification" content="google" />
<meta name="y_key" content="yahoo" />
<meta name="yandex-verification" content="yandex" />
<meta name="me" content="my-email" />
<meta name="me" content="my-link" />
appleWebApp
export const metadata = {
itunes: {
appId: 'myAppStoreID',
appArgument: 'myAppArgument',
},
appleWebApp: {
title: 'Apple Web App',
statusBarStyle: 'black-translucent',
startupImage: [
'/assets/startup/apple-touch-startup-image-768x1004.png',
{
url: '/assets/startup/apple-touch-startup-image-1536x2008.png',
media: '(device-width: 768px) and (device-height: 1024px)',
},
],
},
}
<meta
name="apple-itunes-app"
content="app-id=myAppStoreID, app-argument=myAppArgument"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Apple Web App" />
<link
href="/assets/startup/apple-touch-startup-image-768x1004.png"
rel="apple-touch-startup-image"
/>
<link
href="/assets/startup/apple-touch-startup-image-1536x2008.png"
media="(device-width: 768px) and (device-height: 1024px)"
rel="apple-touch-startup-image"
/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
alternates
export const metadata = {
alternates: {
canonical: 'https://nextjs.org',
languages: {
'en-US': 'https://nextjs.org/en-US',
'de-DE': 'https://nextjs.org/de-DE',
},
media: {
'only screen and (max-width: 600px)': 'https://nextjs.org/mobile',
},
types: {
'application/rss+xml': 'https://nextjs.org/rss',
},
},
}
<link rel="canonical" href="https://nextjs.org" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
<link
rel="alternate"
media="only screen and (max-width: 600px)"
href="https://nextjs.org/mobile"
/>
<link
rel="alternate"
type="application/rss+xml"
href="https://nextjs.org/rss"
/>
appLinks
export const metadata = {
appLinks: {
ios: {
url: 'https://nextjs.org/ios',
app_store_id: 'app_store_id',
},
android: {
package: 'com.example.android/package',
app_name: 'app_name_android',
},
web: {
url: 'https://nextjs.org/web',
should_fallback: true,
},
},
}
<meta property="al:ios:url" content="https://nextjs.org/ios" />
<meta property="al:ios:app_store_id" content="app_store_id" />
<meta property="al:android:package" content="com.example.android/package" />
<meta property="al:android:app_name" content="app_name_android" />
<meta property="al:web:url" content="https://nextjs.org/web" />
<meta property="al:web:should_fallback" content="true" />
archives
Describe una colección de registros, documentos u otros materiales de interés histórico (fuente).
export const metadata = {
archives: ['https://nextjs.org/13'],
}
<link rel="archives" href="https://nextjs.org/13" />
assets
export const metadata = {
assets: ['https://nextjs.org/assets'],
}
<link rel="assets" href="https://nextjs.org/assets" />
bookmarks
export const metadata = {
bookmarks: ['https://nextjs.org/13'],
}
<link rel="bookmarks" href="https://nextjs.org/13" />
category
export const metadata = {
category: 'technology',
}
<meta name="category" content="technology" />
other
Todas las opciones de metadatos deberían estar cubiertas usando el soporte incorporado. Sin embargo, puede haber etiquetas de metadatos personalizadas específicas para su sitio o nuevas etiquetas de metadatos recién lanzadas. Puede usar la opción other
para renderizar cualquier etiqueta de metadatos personalizada.
export const metadata = {
other: {
custom: 'meta',
},
}
<meta name="custom" content="meta" />
Metadatos no admitidos
Los siguientes tipos de metadatos no tienen soporte incorporado actualmente. Sin embargo, aún pueden renderizarse en el layout o página directamente.
Metadato | Recomendación |
---|---|
<meta http-equiv="..."> | Use cabeceras HTTP apropiadas mediante redirect() , Middleware, Cabeceras de Seguridad |
<base> | Renderice la etiqueta en el layout o página directamente. |
<noscript> | Renderice la etiqueta en el layout o página directamente. |
<style> | Más información sobre estilos en Next.js. |
<script> | Más información sobre uso de scripts. |
<link rel="stylesheet" /> | importe hojas de estilo directamente en el layout o página. |
<link rel="preload /> | Use el método preload de ReactDOM |
<link rel="preconnect" /> | Use el método preconnect de ReactDOM |
<link rel="dns-prefetch" /> | Use el método prefetchDNS de ReactDOM |
Pistas de recursos (Resource hints)
El elemento <link>
tiene varias palabras clave rel
que pueden usarse para indicar al navegador que es probable que se necesite un recurso externo. El navegador usa esta información para aplicar optimizaciones de precarga según la palabra clave.
Aunque la API de Metadatos no soporta directamente estas pistas, puede usar los nuevos métodos de ReactDOM
para insertarlas de forma segura en el <head>
del documento.
'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return null
}
'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return null
}
<link rel="preload">
Inicia la carga de un recurso temprano en el ciclo de vida de renderizado de la página (navegador). Documentación MDN.
ReactDOM.preload(href: string, options: { as: string })
<link rel="preload" href="..." as="..." />
<link rel="preconnect">
Inicia preventivamente una conexión a un origen. Documentación MDN.
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
<link rel="preconnect" href="..." crossorigin />
<link rel="dns-prefetch">
Intenta resolver un nombre de dominio antes de que se soliciten los recursos. Documentación MDN.
ReactDOM.prefetchDNS(href: string)
<link rel="dns-prefetch" href="..." />
Nota importante:
- Estos métodos actualmente solo son compatibles en Componentes de Cliente, que aún se renderizan en el servidor en la carga inicial de la página.
- Las características incorporadas de Next.js como
next/font
,next/image
ynext/script
manejan automáticamente las pistas de recursos relevantes.- React 18.3 aún no incluye definiciones de tipos para
ReactDOM.preload
,ReactDOM.preconnect
yReactDOM.preconnectDNS
. Puede usar// @ts-ignore
como solución temporal para evitar errores de tipo.
Tipos
Puede agregar seguridad de tipos a sus metadatos usando el tipo Metadata
. Si está usando el plugin de TypeScript incorporado en su IDE, no necesita agregar manualmente el tipo, pero aún puede hacerlo explícitamente si lo desea.
Objeto metadata
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
Función generateMetadata
Función regular
import type { Metadata } from 'next'
export function generateMetadata(): Metadata {
return {
title: 'Next.js',
}
}
Función asíncrona
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
return {
title: 'Next.js',
}
}
Con props de segmento
import type { Metadata } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
export function generateMetadata({ params, searchParams }: Props): Metadata {
return {
title: 'Next.js',
}
}
export default function Page({ params, searchParams }: Props) {}
Con metadatos padre
import type { Metadata, ResolvingMetadata } from 'next'
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
return {
title: 'Next.js',
}
}
Proyectos JavaScript
Para proyectos JavaScript, puede usar JSDoc para agregar seguridad de tipos.
/** @type {import("next").Metadata} */
export const metadata = {
title: 'Next.js',
}
Historial de versiones
Versión | Cambios |
---|---|
v13.2.0 | Se introdujeron metadata y generateMetadata . |