Метаданные
Next.js имеет API метаданных, который можно использовать для определения метаданных вашего приложения (например, тегов meta и link внутри вашего HTML-элемента head) для улучшения SEO и возможности совместного использования в социальных сетях.
Существует два способа добавления метаданных в ваше приложение:
-
Метаданные на основе конфигурации: Экспортируйте статический
metadataобъект или динамическуюgenerateMetadataфункцию вlayout.jsилиpage.jsфайле. - Метаданные на основе файлов: Добавьте статические или динамически сгенерированные специальные файлы в сегменты маршрутов.
В обоих этих вариантах Next.js автоматически сгенерирует соответствующие <head> элементы для ваших страниц. Вы также можете создавать динамические изображения OG, используя конструктор ImageResponse.
Статические метаданные
Для определения статических метаданных экспортируйте Metadata объект из layout.js или статического page.js файла.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}Все доступные варианты см. в Справочнике API.
Динамические метаданные
Вы можете использовать generateMetadata функцию для fetch метаданных, которые требуют динамических значений.
import type { 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> {
// read route params
const id = params.id
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// optionally access and extend (rather than replace) parent metadata
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) {}Все доступные параметры см. в Справочнике API.
Важно знать:
- Статические и динамические метаданные через
generateMetadataподдерживаются только в компонентах сервера.- Запросы
fetchавтоматически кэшируются для одних и тех же данных во всехgenerateMetadata,generateStaticParams, макетах, страницах и компонентах сервера. Reactcacheможно использовать, еслиfetchнедоступен.- Next.js будет ждать завершения получения данных внутри
generateMetadataперед передачей интерфейса на клиент. Это гарантирует, что первая часть потоковой передачи ответа включает<head>теги.
Метаданные на основе файлов
Для метаданных доступны следующие специальные файлы:
- favicon.ico, apple-icon.jpg и icon.jpg
- opengraph-image.jpg и twitter-image.jpg
- robots.txt
- sitemap.xml
Вы можете использовать их для статических метаданных или программно генерировать эти файлы с помощью кода.
Для реализации и примеров см. Справочник по файлам метаданных и Динамическое создание изображений.
Поведение
Метаданные на основе файлов имеют более высокий приоритет и переопределят любые метаданные на основе конфигурации.
Поля по умолчанию
Существует два тега meta по умолчанию, которые всегда добавляются, даже если маршрут не определяет метаданные:
- Тег meta charset устанавливает кодировку символов для веб-сайта.
- Тег meta viewport устанавливает ширину и масштаб области просмотра веб-сайта для адаптации к различным устройствам.
<meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
Важно знать: Вы можете переопределить тег мета
viewportпо умолчанию.
Порядок
Метаданные оцениваются в порядке от корневого сегмента до сегмента, наиболее близкого к конечному page.js сегменту. Например:
-
app/layout.tsx(Корневой макет) -
app/blog/layout.tsx(Вложенный макет блога) -
app/blog/[slug]/page.tsx(Страница блога)
Объединение
Следуя порядку оценки, объекты метаданных, экспортированные из нескольких сегментов одного маршрута, объединяются вместе поверхностно для формирования конечного результата метаданных маршрута. Дублирующиеся ключи заменяются в соответствии с их порядком.
Это означает, что метаданные со вложенными полями, такими как openGraph и robots, определенные в более раннем сегменте, перезаписываются последним сегментом, их определяющим.
Перезапись полей
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// Output:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />В примере выше:
-
titleизapp/layout.jsзаменяется наtitleвapp/blog/page.js. - Все
openGraphполя изapp/layout.jsзаменяются вapp/blog/page.js, потому чтоapp/blog/page.jsустанавливает метаданныеopenGraph. Обратите внимание на отсутствиеopenGraph.description.
Если вы хотите поделиться некоторыми вложенными полями между сегментами, одновременно перезаписывая другие, вы можете вынести их в отдельную переменную:
export const openGraphImage = { images: ['http://...'] }import { openGraphImage } from './shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'Home',
},
}import { openGraphImage } from '../shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'About',
},
}В примере выше изображение OG разделено между app/layout.js и app/about/page.js, в то время как заголовки разные.
Наследование полей
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}export const metadata = {
title: 'About',
}
// Output:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme is a..." />Примечания
-
titleизapp/layout.jsзаменяется наtitleвapp/about/page.js. - Все
openGraphполя изapp/layout.jsунаследованы вapp/about/page.js, потому чтоapp/about/page.jsне устанавливает метаданныеopenGraph.
Динамическое создание изображений
Конструктор ImageResponse позволяет создавать динамические изображения с использованием JSX и CSS. Это полезно для создания изображений для социальных сетей, таких как изображения Open Graph, карточки Twitter и т. д.
ImageResponse использует Edge Runtime, и Next.js автоматически добавляет правильные заголовки к кэшированным изображениям на границе, что помогает улучшить производительность и уменьшить повторные вычисления.
Чтобы использовать его, вы можете импортировать ImageResponse из next/og:
import { ImageResponse } from 'next/og'
export const runtime = 'edge'
export async function GET() {
return new ImageResponse(
(
<div
style={{
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
}}
>
Hello world!
</div>
),
{
width: 1200,
height: 600,
}
)
}ImageResponse хорошо интегрируется с другими API Next.js, включая Обработчики маршрутов и метаданные на основе файлов. Например, вы можете использовать ImageResponse в opengraph-image.tsx файле для генерации изображений Open Graph во время сборки или динамически во время запроса.
ImageResponse поддерживает общие свойства CSS, включая flexbox и абсолютное позиционирование, пользовательские шрифты, перенос текста, центрирование и вложенные изображения. Полный список поддерживаемых свойств CSS.
Важно знать:
- Примеры доступны в Vercel OG Playground.
ImageResponseиспользует @vercel/og, Satori и Resvg для преобразования HTML и CSS в PNG.- Поддерживается только Edge Runtime. Стандартный Node.js runtime не будет работать.
- Поддерживается только flexbox и подмножество свойств CSS. Расширенные макеты (например,
display: grid) не будут работать.- Максимальный размер пакета
500KB. Размер пакета включает ваш JSX, CSS, шрифты, изображения и любые другие ресурсы. Если вы превысите этот предел, рассмотрите возможность уменьшения размера ресурсов или загрузки во время выполнения.- Поддерживаются только
ttf,otf, иwoffформаты шрифтов. Для максимальной скорости разбора шрифтовttfилиotfпредпочтительнееwoff.
JSON-LD
JSON-LD — это формат структурированных данных, который может использоваться поисковыми системами для понимания вашего контента. Например, вы можете использовать его для описания человека, события, организации, фильма, книги, рецепта и многих других типов сущностей.
В настоящее время рекомендуется отображать структурированные данные в качестве тега <script> в ваших компонентах layout.js или page.js. Например:
export default async function Page({ params }) {
const product = await getProduct(params.id)
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
}
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
)
}Вы можете проверить и протестировать свои структурированные данные с помощью Rich Results Test для Google или универсального Schema Markup Validator.
END_OF_DOCUMENT_MARKERВы можете набрать свой JSON-LD с TypeScript, используя пакеты сообщества, такие как schema-dts:
import { Product, WithContext } from 'schema-dts'
const jsonLd: WithContext<Product> = {
'@context': 'https://schema.org',
'@type': 'Product',
name: 'Next.js Sticker',
image: 'https://nextjs.org/imgs/sticker.png',
description: 'Dynamic at the speed of static.',
}
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/app/building-your-application/optimizing/metadata