1. Введение
Вы когда-нибудь задумывались, почему одни сайты легко находятся в поисковиках, а другие — словно спрятаны в лесу? Или почему при репосте ссылки в Telegram или Facebook появляется красивая карточка с картинкой и описанием, а иногда просто унылая ссылка?
Всё дело в SEO-метаданных и специальных тегах для социальных сетей. Они помогают:
- Поисковым системам понять, о чём ваша страница.
- Соцсетям красиво отображать ваш сайт при репосте.
- Пользователям быстрее находить ваш сайт по нужным ключевым словам.
- Браузерам показывать симпатичную иконку на вкладке (favicon).
Если ваш сайт — это герой, то SEO-метаданные — его костюм, визитка и реклама сразу. Без них ваш герой может быть очень классным, но никто о нём не узнает.
Какие бывают SEO-метаданные?
В мире HTML и Next.js под SEO-метаданными обычно понимают:
- <title> — заголовок страницы (отображается на вкладке браузера и в поиске).
- <meta name="description"> — короткое описание страницы.
- Open Graph-теги (для Facebook, Telegram, VK и др.): <meta property="og:...">
- Twitter Cards: <meta name="twitter:...">
- Favicons: <link rel="icon" ...>, <link rel="apple-touch-icon" ...>
- Canonical-ссылки: <link rel="canonical" ...>
- Meta robots: <meta name="robots" ...>
В Next.js 13+ (и, конечно, в 15) всё это можно (и нужно!) описывать декларативно — через объект metadata или функцию generateMetadata.
2. Как добавить SEO-метаданные в Next.js 15 (App Router)
Базовые метаданные через объект metadata
Каждая страница или layout в папке app/ может экспортировать объект metadata:
export const metadata = {
title: "Главная страница — Мой Крутой Сайт",
description: "Лучший сайт для изучения Next.js и frontend-разработки!"
}
Next.js сам сгенерирует <title> и <meta name="description"> для этой страницы. Это уже большой плюс для поисковиков!
Динамическая генерация метаданных
Если вам нужно подставлять данные из API или параметров маршрута (например, название статьи):
// app/blog/[slug]/page.tsx
import { getPost } from "@/lib/api";
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.summary,
};
}
Теперь каждая статья будет иметь свой уникальный заголовок и описание.
3. Open Graph: чтобы соцсети любили ваш сайт
Что такое Open Graph?
Open Graph — это набор специальных meta-тегов, которые позволяют соцсетям (Facebook, Telegram, VK и др.) красиво отображать ваши страницы при репосте. Вот пример карточки:
+-------------------------------------+
| [Картинка] |
| Заголовок страницы |
| Описание страницы |
| example.com |
+-------------------------------------+
Какие теги нужны?
Минимальный набор:
<meta property="og:title" content="Название страницы">
<meta property="og:description" content="Описание страницы">
<meta property="og:image" content="https://example.com/cover.jpg">
<meta property="og:url" content="https://example.com/page">
<meta property="og:type" content="website">
Как добавить Open Graph в Next.js?
Просто расширьте объект metadata:
export const metadata = {
title: "Главная страница — Мой Крутой Сайт",
description: "Лучший сайт для изучения Next.js и frontend-разработки!",
openGraph: {
title: "Главная страница — Мой Крутой Сайт",
description: "Здесь вы узнаете всё о фронтенде!",
url: "https://example.com",
siteName: "Мой Крутой Сайт",
images: [
{
url: "https://example.com/og-image.jpg",
width: 1200,
height: 630,
alt: "Картинка для соцсетей"
}
],
locale: "ru_RU",
type: "website"
}
}
Next.js сам сгенерирует нужные <meta property="og:..."> теги в <head>.
Для динамических страниц:
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.summary,
openGraph: {
title: post.title,
description: post.summary,
url: `https://example.com/blog/${params.slug}`,
images: [
{
url: post.coverUrl,
width: 1200,
height: 630,
alt: post.title
}
],
type: "article"
}
}
}
4. Twitter Cards: чтобы твиты были красивыми
Twitter (X) использует свои meta-теги, но Next.js тоже их поддерживает через объект twitter:
export const metadata = {
twitter: {
card: "summary_large_image",
title: "Главная страница — Мой Крутой Сайт",
description: "Изучайте фронтенд с нами!",
site: "@myTwitterHandle",
images: ["https://example.com/og-image.jpg"]
}
}
Next.js сгенерирует теги:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Главная страница — Мой Крутой Сайт">
<meta name="twitter:description" content="Изучайте фронтенд с нами!">
<meta name="twitter:site" content="@myTwitterHandle">
<meta name="twitter:image" content="https://example.com/og-image.jpg">
5. Favicons: маленькая, но важная деталь
Что такое favicon?
Favicon — это маленькая иконка, которую браузер показывает на вкладке рядом с названием сайта. Без неё ваш сайт выглядит как "гость без бейджа" — вроде и пришёл, а вроде и никто не знает, кто это.
Как добавить favicon в Next.js 15 (App Router)?
Вариант 1: просто положить favicon.ico в public/
- Положите файл favicon.ico в папку public/ вашего проекта.
- Next.js автоматически добавит нужный тег:
<link rel="icon" href="/favicon.ico" sizes="any">
Вариант 2: добавить разные размеры и иконки для устройств Apple
Положите в public/ дополнительные файлы:
- favicon.ico — для обычных браузеров.
- icon.svg — для современных браузеров.
- apple-touch-icon.png — для iOS/Apple устройств.
Next.js автоматически добавит теги (если такие файлы найдёт):
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" type="image/svg+xml" href="/icon.svg">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
Вариант 3: явно указать favicon через объект metadata
export const metadata = {
icons: {
icon: "/favicon.ico",
shortcut: "/favicon.ico",
apple: "/apple-touch-icon.png",
other: {
rel: "mask-icon",
url: "/safari-pinned-tab.svg",
color: "#5bbad5"
}
}
}
Лайфхак: Используйте бесплатные генераторы favicon (например, realfavicongenerator.net), чтобы быстро получить все нужные форматы и размеры.
6. Canonical-ссылки и robots
Canonical
Если одна и та же страница доступна по разным адресам (например, с / на конце и без), поисковики могут запутаться. Canonical-ссылка подсказывает, какой адрес "главный":
export const metadata = {
alternates: {
canonical: "https://example.com/blog/post-123"
}
}
Next.js сгенерирует:
<link rel="canonical" href="https://example.com/blog/post-123">
Meta robots
Если вы не хотите, чтобы страницу индексировали поисковики:
export const metadata = {
robots: {
index: false,
follow: false,
nocache: true
}
}
Next.js сгенерирует:
<meta name="robots" content="noindex, nofollow, noarchive">
7. Пример: SEO для страницы блога
Давайте соберём всё вместе — пример для страницы поста блога, где используются все основные SEO-метаданные, Open Graph, Twitter и favicon.
// app/blog/[slug]/page.tsx
import { getPost } from "@/lib/api";
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.summary,
openGraph: {
title: post.title,
description: post.summary,
url: `https://example.com/blog/${params.slug}`,
type: "article",
images: [
{
url: post.coverUrl,
width: 1200,
height: 630,
alt: post.title
}
]
},
twitter: {
card: "summary_large_image",
title: post.title,
description: post.summary,
images: [post.coverUrl]
},
icons: {
icon: "/favicon.ico",
apple: "/apple-touch-icon.png"
},
alternates: {
canonical: `https://example.com/blog/${params.slug}`
}
};
}
8. Типичные ошибки при работе с SEO-метаданными, Open Graph и favicon
Ошибка №1: Нет уникальных метаданных для каждой страницы.
Если у всех страниц одинаковый <title> и <meta name="description">, поисковики будут считать ваш сайт неоригинальным. Используйте динамическую генерацию метаданных!
Ошибка №2: Картинка для Open Graph не по размеру или не по адресу.
Рекомендуемый размер для og:image — 1200x630 px. Если картинка не доступна по внешнему URL или слишком маленькая, соцсети покажут "серую" карточку.
Ошибка №3: Нет favicon или он слишком большого размера.
Файл favicon.ico должен быть 16x16 или 32x32 px. Если положить туда картинку 5 мегабайт, браузер "обидится".
Ошибка №4: Иконки лежат не в папке public/
В Next.js 15 (App Router) все статические файлы должны быть в папке public/. Если положить favicon в другую папку — браузер его не найдёт.
Ошибка №5: Дублирующиеся canonical-ссылки или их отсутствие.
Если canonical не указан, поисковики могут запутаться, а если их несколько — будет конфликт.
Ошибка №6: Не обновили кэш favicon.
Браузеры любят кэшировать favicon. Если вы её изменили, попробуйте сменить имя файла или добавить query-параметр (например, /favicon.ico?v=2).
Ошибка №7: Неправильные типы файлов для иконок.
SVG-иконки поддерживаются не всеми браузерами как favicon. Для универсальности используйте и ICO, и PNG, и SVG.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ