Объект Metadata и параметры generateMetadata
Эта страница охватывает все параметры Config-based Metadata с использованием generateMetadata
и статического объекта metadata.
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' }],
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', // Должен быть абсолютным URL
width: 800,
height: 600,
},
{
url: 'https://nextjs.org/og-alt.png', // Должен быть абсолютным URL
width: 1800,
height: 1600,
alt: 'Мой альтернативный текст',
},
],
videos: [
{
url: 'https://nextjs.org/video.mp4', // Должен быть абсолютным URL
width: 800,
height: 600,
},
],
audio: [
{
url: 'https://nextjs.org/audio.mp3', // Должен быть абсолютным URL
},
],
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:video" content="https://nextjs.org/video.mp4" />
<meta property="og:video:width" content="800" />
<meta property="og:video:height" content="600" />
<meta property="og:audio" content="https://nextjs.org/audio.mp3" />
<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'),
{ url: '/icon-dark.png', media: '(prefers-color-scheme: dark)' },
],
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="icon" href="https://example.com/icon.png" />
<link rel="icon" href="/icon-dark.png" media="(prefers-color-scheme: dark)" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
rel="apple-touch-icon-precomposed"
href="/apple-touch-icon-precomposed.png"
/>
<link
rel="apple-touch-icon"
href="/apple-icon-x3.png"
sizes="180x180"
type="image/png"
/>
Полезно знать: Мета-теги
msapplication-*
больше не поддерживаются в Chromium-сборках Microsoft Edge и больше не нужны.
themeColor
Устарело: Опция
themeColor
вmetadata
устарела в Next.js 14. Вместо неё используйтеviewport
конфигурацию.
manifest
Манифест веб-приложения, как определено в спецификации Web Application Manifest.
export const metadata = {
manifest: 'https://nextjs.org/manifest.json',
}
<link rel="manifest" href="https://nextjs.org/manifest.json" />
twitter
Спецификация Twitter используется (что удивительно) не только для X (ранее известного как 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'], // Должен быть абсолютным URL
},
}
<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
Устарело: Опция
viewport
вmetadata
устарела в Next.js 14. Вместо неё используйтеviewport
конфигурацию.
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" />
facebook
Вы можете подключить приложение Facebook или аккаунт Facebook к вашей веб-странице для определённых Facebook Social Plugins Документация Facebook
Полезно знать: Можно указать либо appId, либо admins, но не оба одновременно.
export const metadata = {
facebook: {
appId: '12345678',
},
}
<meta property="fb:app_id" content="12345678" />
export const metadata = {
facebook: {
admins: '12345678',
},
}
<meta property="fb:admins" content="12345678" />
Если нужно сгенерировать несколько мета-тегов fb:admins, можно использовать массив значений.
export const metadata = {
facebook: {
admins: ['12345678', '87654321'],
},
}
<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />
other
Все варианты метаданных должны быть покрыты встроенной поддержкой. Однако могут быть пользовательские мета-теги, специфичные для вашего сайта, или только что выпущенные новые мета-теги. Вы можете использовать опцию other
для рендеринга любых пользовательских мета-тегов.
export const metadata = {
other: {
custom: 'meta',
},
}
<meta name="custom" content="meta" />
Если нужно сгенерировать несколько мета-тегов с одинаковым ключом, можно использовать массив значений.
export const metadata = {
other: {
custom: ['meta1', 'meta2'],
},
}
<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />
Неподдерживаемые метаданные
Следующие типы метаданных в настоящее время не имеют встроенной поддержки. Однако их всё ещё можно отображать в самом макете или странице.
Метаданные | Рекомендация |
---|---|
<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="..." />
Полезно знать:
- В настоящее время эти методы поддерживаются только в клиентских компонентах (Client Components), которые по-прежнему рендерятся на стороне сервера при первоначальной загрузке страницы.
- Встроенные функции 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 | viewport , themeColor и colorScheme устарели в пользу конфигурации viewport . |
v13.2.0 | Введены metadata и generateMetadata . |