Объект Metadata и параметры generateMetadata
Эта страница охватывает все варианты Config-based Metadata с использованием generateMetadata
и статического объекта метаданных.
import { Metadata } from 'next'
// Статические метаданные
export const metadata: Metadata = {
title: '...',
}
// Или динамические метаданные
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
// Статические метаданные
export const metadata = {
title: '...',
}
// Или динамические метаданные
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
Полезно знать:
- Экспорт объекта
metadata
и функцииgenerateMetadata
поддерживается только в Server Components.- Нельзя одновременно экспортировать и объект
metadata
, и функциюgenerateMetadata
из одного сегмента маршрута.
Объект metadata
Для определения статических метаданных экспортируйте объект Metadata
из файла layout.js
или 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() {}
Полный список поддерживаемых параметров смотрите в разделе Поля Metadata.
Функция generateMetadata
Динамические метаданные, зависящие от динамической информации, такой как параметры текущего маршрута, внешние данные или metadata
в родительских сегментах, могут быть заданы с помощью экспорта функции generateMetadata
, которая возвращает объект 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> {
// Чтение параметров маршрута
const id = params.id
// Получение данных
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// Опциональное использование и расширение (а не замена) родительских метаданных
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) {
// Чтение параметров маршрута
const id = params.id
// Получение данных
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// Опциональное использование и расширение (а не замена) родительских метаданных
const previousImages = (await parent).openGraph?.images || []
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
export default function Page({ params, searchParams }) {}
Параметры
Функция generateMetadata
принимает следующие параметры:
-
props
- Объект, содержащий параметры текущего маршрута:-
params
- Объект, содержащий параметры динамического маршрута от корневого сегмента до сегмента, из которого вызываетсяgenerateMetadata
. Примеры:Маршрут 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
- Объект, содержащий параметры поиска текущего URL. Примеры: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
- Промис, содержащий разрешенные метаданные из родительских сегментов маршрута.
Возвращаемое значение
Функция generateMetadata
должна возвращать объект Metadata
, содержащий одно или несколько полей метаданных.
Полезно знать:
- Если метаданные не зависят от информации во время выполнения, их следует определять с помощью статического объекта
metadata
, а неgenerateMetadata
.- Запросы
fetch
автоматически мемоизируются для одинаковых данных вgenerateMetadata
,generateStaticParams
, Layouts, Pages и Server Components. Reactcache
можно использовать, еслиfetch
недоступен.searchParams
доступны только в сегментахpage.js
.- Методы Next.js
redirect()
иnotFound()
также могут использоваться внутриgenerateMetadata
.
Поля Metadata
title
Атрибут title
используется для установки заголовка документа. Он может быть определен как простая строка или необязательный шаблонный объект.
Строка
export const metadata = {
title: 'Next.js',
}
<title>Next.js</title>
Шаблонный объект
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '...',
default: '...',
absolute: '...',
},
}
export const metadata = {
title: {
default: '...',
template: '...',
absolute: '...',
},
}
Default
title.default
можно использовать для предоставления запасного заголовка дочерним сегментам маршрута, которые не определяют title
.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
default: 'Acme',
},
}
import type { Metadata } from 'next'
export const metadata: Metadata = {}
// Вывод: <title>Acme</title>
Template
title.template
можно использовать для добавления префикса или суффикса к titles
, определенным в дочерних сегментах маршрута.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // при создании шаблона требуется значение по умолчанию
},
}
export const metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // при создании шаблона требуется значение по умолчанию
},
}
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About',
}
// Вывод: <title>About | Acme</title>
export const metadata = {
title: 'About',
}
// Вывод: <title>About | Acme</title>
Полезно знать:
title.template
применяется к дочерним сегментам маршрута, а не к сегменту, в котором он определен. Это означает:
title.default
обязателен при добавленииtitle.template
.title.template
, определенный вlayout.js
, не будет применяться кtitle
, определенному вpage.js
того же сегмента маршрута.title.template
, определенный вpage.js
, не имеет эффекта, потому что страница всегда является конечным сегментом (у нее нет дочерних сегментов маршрута).
title.template
не имеет эффекта, если маршрут не определилtitle
илиtitle.default
.
Absolute
title.absolute
можно использовать для предоставления заголовка, который игнорирует title.template
, установленный в родительских сегментах.
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',
},
}
// Вывод: <title>About</title>
export const metadata = {
title: {
absolute: 'About',
},
}
// Вывод: <title>About</title>
Полезно знать:
layout.js
title
(строка) иtitle.default
определяют заголовок по умолчанию для дочерних сегментов (которые не определяют свой собственныйtitle
). Они будут дополнятьtitle.template
из ближайшего родительского сегмента, если он существует.title.absolute
определяет заголовок по умолчанию для дочерних сегментов. Он игнорируетtitle.template
из родительских сегментов.title.template
определяет новый шаблон заголовка для дочерних сегментов.
page.js
- Если страница не определяет свой собственный заголовок, будет использоваться заголовок ближайшего родителя.
title
(строка) определяет заголовок маршрута. Он будет дополнятьtitle.template
из ближайшего родительского сегмента, если он существует.title.absolute
определяет заголовок маршрута. Он игнорируетtitle.template
из родительских сегментов.title.template
не имеет эффекта вpage.js
, потому что страница всегда является конечным сегментом маршрута.
description
export const metadata = {
description: 'The React Framework for the Web',
}
<meta name="description" content="The React Framework for the Web" />
Базовые поля
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
- это удобный параметр для установки базового префикса URL для полей metadata
, которые требуют полного URL.
metadataBase
позволяет полямmetadata
, основанным на URL, определенным в текущем сегменте маршрута и ниже, использовать относительный путь вместо обязательного абсолютного URL.- Относительный путь поля будет объединен с
metadataBase
для формирования полного URL. - Если не настроен,
metadataBase
автоматически заполняется значением по умолчанию.
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" />
Полезно знать:
metadataBase
обычно устанавливается в корневомapp/layout.js
, чтобы применяться к полямmetadata
, основанным на URL, во всех маршрутах.- Все поля
metadata
, основанные на URL, которые требуют абсолютных URL, могут быть настроены с помощью параметраmetadataBase
.metadataBase
может содержать поддомен, напримерhttps://app.acme.com
, или базовый путь, напримерhttps://acme.com/start/from/here
.- Если поле
metadata
предоставляет абсолютный URL,metadataBase
будет проигнорирован.- Использование относительного пути в поле
metadata
, основанном на URL, без настройкиmetadataBase
вызовет ошибку сборки.- Next.js нормализует дублирующиеся слеши между
metadataBase
(например,https://acme.com/
) и относительным полем (например,/path
) до одного слеша (например,https://acme.com/path
).
Значение по умолчанию
Если не настроено, metadataBase
имеет значение по умолчанию:
- Когда обнаружен
VERCEL_URL
:https://${process.env.VERCEL_URL}
, в противном случае используетсяhttp://localhost:${process.env.PORT || 3000}
. - При переопределении значения по умолчанию рекомендуется использовать переменные окружения для вычисления URL. Это позволяет настроить URL для локальной разработки, тестирования и рабочих окружений.
Композиция URL
Композиция URL отдает предпочтение намерениям разработчика перед семантикой обхода директорий по умолчанию.
- Дублирующиеся слеши между
metadataBase
и полямиmetadata
нормализуются. - "Абсолютный" путь в поле
metadata
(который обычно заменяет весь путь URL) рассматривается как "относительный" путь (начиная с концаmetadataBase
).
Например, для следующего metadataBase
:
import { Metadata } from 'next'
export const metadata: Metadata = {
metadataBase: new URL('https://acme.com'),
}
export const metadata = {
metadataBase: new URL('https://acme.com'),
}
Любые поля metadata
, которые наследуют вышеуказанный metadataBase
и устанавливают собственное значение, будут разрешены следующим образом:
Поле metadata | Разрешенный URL |
---|---|
/ | 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: 'Мой альтернативный текст',
},
],
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="Мой альтернативный текст" />
<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" />
Полезно знать:
- Для изображений Open Graph может быть удобнее использовать файловый Metadata API. Вместо синхронизации конфигурации с реальными файлами, файловый API автоматически сгенерирует правильные метаданные.
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
Полезно знать: Рекомендуем использовать файловый Metadata API для иконок, где это возможно. Вместо синхронизации конфигурации с реальными файлами, файловый API автоматически сгенерирует правильные метаданные.
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"
/>
Полезно знать: Мета-теги
msapplication-*
больше не поддерживаются в Chromium-сборках Microsoft Edge и больше не требуются.
themeColor
Подробнее о theme-color.
Простой цвет темы
export const metadata = {
themeColor: 'black',
}
<meta name="theme-color" content="black" />
С атрибутом 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
Манифест веб-приложения, как определено в спецификации Web Application Manifest.
export const metadata = {
manifest: 'https://nextjs.org/manifest.json',
}
<link rel="manifest" href="https://nextjs.org/manifest.json" />
twitter
Подробнее о Twitter Card markup reference.
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',
},
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" />
<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
Полезно знать: Мета-тег
viewport
автоматически устанавливается со следующими значениями по умолчанию. Обычно ручная настройка не требуется, так как значения по умолчанию достаточны. Однако информация предоставлена для полноты.
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
Описывает коллекцию записей, документов или других материалов, представляющих исторический интерес (источник).
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
Все варианты метаданных должны быть покрыты встроенной поддержкой. Однако могут быть пользовательские мета-теги, специфичные для вашего сайта, или новые мета-теги, только что выпущенные. Вы можете использовать опцию other
для рендеринга любых пользовательских мета-тегов.
export const metadata = {
other: {
custom: 'meta',
},
}
<meta name="custom" content="meta" />
Неподдерживаемые метаданные
Следующие типы метаданных в настоящее время не имеют встроенной поддержки. Однако их всё ещё можно отображать в самом макете или странице.
Метаданные | Рекомендация |
---|---|
<meta http-equiv="..."> | Используйте соответствующие HTTP-заголовки через redirect() , Middleware, Security Headers |
<base> | Отобразите тег в самом макете или странице. |
<noscript> | Отобразите тег в самом макете или странице. |
<style> | Узнайте больше о стилизации в Next.js. |
<script> | Узнайте больше об использовании скриптов. |
<link rel="stylesheet" /> | Импортируйте таблицы стилей напрямую в макете или странице. |
<link rel="preload /> | Используйте метод preload из ReactDOM |
<link rel="preconnect" /> | Используйте метод preconnect из ReactDOM |
<link rel="dns-prefetch" /> | Используйте метод prefetchDNS из ReactDOM |
Ресурсные подсказки
Элемент <link>
имеет ряд ключевых слов rel
, которые можно использовать, чтобы указать браузеру, что внешний ресурс, скорее всего, понадобится. Браузер использует эту информацию для применения оптимизаций предварительной загрузки в зависимости от ключевого слова.
Хотя API метаданных напрямую не поддерживает эти подсказки, вы можете использовать новые методы ReactDOM
для безопасного их добавления в <head>
документа.
'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">
Начинает загрузку ресурса на раннем этапе жизненного цикла отрисовки страницы (в браузере). Документация MDN.
ReactDOM.preload(href: string, options: { as: string })
<link rel="preload" href="..." as="..." />
<link rel="preconnect">
Заблаговременно инициирует подключение к источнику. Документация MDN.
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
<link rel="preconnect" href="..." crossorigin />
<link rel="dns-prefetch">
Пытается разрешить доменное имя до запроса ресурсов. Документация MDN.
ReactDOM.prefetchDNS(href: string)
<link rel="dns-prefetch" href="..." />
Полезно знать:
- Эти методы в настоящее время поддерживаются только в клиентских компонентах, которые всё ещё отрисовываются на стороне сервера при первоначальной загрузке страницы.
- Встроенные функции Next.js, такие как
next/font
,next/image
иnext/script
, автоматически обрабатывают соответствующие ресурсные подсказки.- React 18.3 пока не включает определения типов для
ReactDOM.preload
,ReactDOM.preconnect
иReactDOM.preconnectDNS
. Вы можете использовать// @ts-ignore
в качестве временного решения, чтобы избежать ошибок типов.
Типы
Вы можете добавить проверку типов к вашим метаданным, используя тип Metadata
. Если вы используете встроенный плагин TypeScript в вашей IDE, вам не нужно вручную добавлять тип, но вы всё ещё можете явно указать его, если хотите.
Объект metadata
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
Функция generateMetadata
Обычная функция
import type { Metadata } from 'next'
export function generateMetadata(): Metadata {
return {
title: 'Next.js',
}
}
Асинхронная функция
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
return {
title: 'Next.js',
}
}
С параметрами сегмента
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) {}
С родительскими метаданными
import type { Metadata, ResolvingMetadata } from 'next'
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
return {
title: 'Next.js',
}
}
JavaScript-проекты
Для JavaScript-проектов вы можете использовать JSDoc для добавления проверки типов.
/** @type {import("next").Metadata} */
export const metadata = {
title: 'Next.js',
}
История версий
Версия | Изменения |
---|---|
v13.2.0 | Введены metadata и generateMetadata . |