Пошук уроків, статей та іншого контенту
Навчитеся задавати незмінні метадані через об’єкт metadata у layout.tsx і page.tsx.
Метадані — це інформація про вебсторінку, яку браузери, пошукові системи та соціальні мережі можуть використовувати для її опису.
До метаданих належать:
заголовок сторінки у вкладці браузера;
опис сторінки;
налаштування для пошукових роботів;
дані для попереднього перегляду сторінки в соціальних мережах.
У Next.js з App Router статичні метадані задають через експорт об’єкта metadata у файлах:
app/layout.tsx;
app/page.tsx;
інших файлах page.tsx або layout.tsx у дереві маршрутів.
Статичні метадані підходять для сторінок, де значення не змінюються залежно від параметрів URL чи даних користувача.
metadata у layout.tsxФайл layout.tsx може містити метадані, спільні для всіх сторінок усередині цього layout.
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Мій Next.js сайт",
description: "Навчальний сайт, створений за допомогою Next.js",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>{children}</body>
</html>
);
}У цьому прикладі:
title задає заголовок сторінки у вкладці браузера;
description задає короткий опис сторінки;
Metadata перевіряє правильність структури об’єкта TypeScript;
метадані з кореневого layout.tsx доступні для сторінок усередині app.
Кореневий layout зазвичай розташований у файлі:
app/layout.tsxpage.tsxОкрема сторінка може мати власні метадані.
Наприклад, структура проєкту:
app/
layout.tsx
page.tsx
about/
page.tsxКореневий layout:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Мій сайт",
description: "Головний опис сайту",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>{children}</body>
</html>
);
}Головна сторінка:
export default function HomePage() {
return (
<main>
<h1>Головна сторінка</h1>
<p>Ласкаво просимо на сайт.</p>
</main>
);
}Сторінка «Про нас» із власними метаданими:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Про нас",
description: "Дізнайтеся більше про нашу команду",
};
export default function AboutPage() {
return (
<main>
<h1>Про нас</h1>
<p>Ми створюємо вебзастосунки за допомогою Next.js.</p>
</main>
);
}Для маршруту /about Next.js використає:
title: "Про нас";
description: "Дізнайтеся більше про нашу команду".
Метадані сторінки мають пріоритет над метаданими layout для тих самих властивостей.
Layout може задавати базові метадані для всіх дочірніх сторінок.
Наприклад:
app/
layout.tsx
dashboard/
layout.tsx
page.tsxКореневий layout:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Мій застосунок",
description: "Опис мого застосунку",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>{children}</body>
</html>
);
}Layout для розділу dashboard:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Панель керування",
};
export default function DashboardLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return <section>{children}</section>;
}Сторінка app/dashboard/page.tsx успадкує метадані з батьківських layout. Значення title буде взято з найближчого layout — у цьому випадку "Панель керування".
Якщо дочірній файл задає власну властивість, вона замінює значення батьківського layout. Інші властивості можуть залишитися успадкованими.
Наприклад, для сторінки:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Звіти",
};
export default function ReportsPage() {
return (
<main>
<h1>Звіти</h1>
</main>
);
}заголовок буде "Звіти", а опис може залишитися успадкованим із кореневого layout.
Об’єкт Metadata підтримує багато властивостей. Для початку найчастіше використовують такі:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Каталог товарів",
description: "Перегляньте доступні товари в нашому каталозі",
keywords: ["товари", "каталог", "покупки"],
authors: [{ name: "Команда магазину" }],
};Основні властивості:
title — заголовок сторінки;
description — короткий опис сторінки;
keywords — ключові слова;
authors — автори сторінки.
Для простої статичної сторінки достатньо title і description.
У layout можна створити шаблон заголовка для дочірніх сторінок. Для цього title задають як об’єкт:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: {
default: "Мій сайт",
template: "%s | Мій сайт",
},
description: "Опис мого сайту",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>{children}</body>
</html>
);
}Тепер сторінка з такими метаданими:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Контакти",
};
export default function ContactsPage() {
return (
<main>
<h1>Контакти</h1>
</main>
);
}отримає заголовок:
Контакти | Мій сайтВластивість default використовується, якщо сторінка не задала власний заголовок.
Шаблон template застосовується до заголовків дочірніх сторінок, але не до заголовка, заданого в тому самому layout.
Структура файлів:
app/
layout.tsx
page.tsx
contacts/
page.tsxФайл app/layout.tsx:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: {
default: "Моя компанія",
template: "%s | Моя компанія",
},
description: "Офіційний сайт моєї компанії",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="uk">
<body>{children}</body>
</html>
);
}Файл app/page.tsx:
export default function HomePage() {
return (
<main>
<h1>Головна сторінка</h1>
<p>Вітаємо на сайті нашої компанії.</p>
</main>
);
}Файл app/contacts/page.tsx:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Контакти",
description: "Зв’яжіться з нашою компанією",
};
export default function ContactsPage() {
return (
<main>
<h1>Контакти</h1>
<p>Наша контактна інформація.</p>
</main>
);
}Результат:
головна сторінка використовує заголовок за замовчуванням Моя компанія;
сторінка /contacts використовує заголовок Контакти | Моя компанія;
сторінка /contacts має власний опис;
мова документа встановлена як українська через lang="uk".
Статичний експорт metadata використовують у серверних компонентах.
Не можна додавати metadata до файлу, який має директиву "use client":
"use client";
import type { Metadata } from "next";
// Некоректно для Client Component
export const metadata: Metadata = {
title: "Сторінка",
};Якщо сторінці потрібні інтерактивні елементи, можна залишити сам page.tsx серверним і винести інтерактивну частину в окремий Client Component.
Також metadata потрібно експортувати як іменований експорт:
export const metadata: Metadata = {
title: "Сторінка",
};Це не те саме, що експорт компонента сторінки за замовчуванням:
export default function Page() {
return <h1>Сторінка</h1>;
}Обидва експорти можуть знаходитися в одному файлі.
headУ старих підходах до React або Next.js метадані могли додаватися через компонент Head. Для App Router статичні метадані потрібно задавати через export const metadata.
Правильно:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Про нас",
};metadata у Client ComponentФайл із "use client" не може експортувати статичні метадані. Перенесіть metadata до серверного layout.tsx або page.tsx.
MetadataTypeScript може виявити помилки в назвах або структурі властивостей, якщо імпортувати тип:
import type { Metadata } from "next";Після цього об’єкт можна оголосити так:
export const metadata: Metadata = {
title: "Головна",
description: "Опис головної сторінки",
};Дочірня сторінка може перевизначити title. Якщо потрібен спільний формат заголовків, використовуйте template у layout.
Статичні метадані задають через експорт metadata.
Об’єкт metadata можна оголосити в layout.tsx або page.tsx.
Метадані layout успадковуються дочірніми сторінками.
Метадані сторінки мають пріоритет над відповідними метаданими layout.
Тип Metadata допомагає правильно описати об’єкт.
Для спільного формату заголовків можна використати title.template.
Статичні метадані не можна експортувати з Client Component.