Настройка SEO для сайта на Next
SEO для Next.js на RelaxDev — полный гайд
Всё, что нужно сделать, чтобы сайт попал в поисковики. Специфика Next.js App Router: robots и sitemap задаются TypeScript-файлами в папке app/, файлы подтверждения лежат в public/.
1. robots.txt
Создайте src/app/robots.ts — Next.js сам отдаст его по адресу /robots.txt:
// src/app/robots.ts
import type { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/dashboard/', '/profile/', '/admin/', '/login/', '/auth/'],
},
],
sitemap: 'https://ваш-домен.ru/sitemap.xml',
};
}
Проверка: откройте https://ваш-домен.ru/robots.txt — должен открыться текст со списком правил.
2. sitemap.xml
Создайте src/app/sitemap.ts:
// src/app/sitemap.ts
import type { MetadataRoute } from 'next';
export const dynamic = 'force-dynamic';
export default function sitemap(): MetadataRoute.Sitemap {
return [
{ url: 'https://ваш-домен.ru', lastModified: new Date(), changeFrequency: 'weekly', priority: 1 },
{ url: 'https://ваш-домен.ru/about', lastModified: new Date(), changeFrequency: 'monthly', priority: 0.8 },
];
}
С динамическим контентом из базы (Prisma):
import type { MetadataRoute } from 'next';
import { prisma } from '@/lib/prisma';
export const dynamic = 'force-dynamic';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = 'https://ваш-домен.ru';
const posts = await prisma.post.findMany({
where: { published: true },
select: { slug: true, updatedAt: true },
});
return [
{ url: baseUrl, lastModified: new Date(), changeFrequency: 'weekly', priority: 1 },
{ url: `${baseUrl}/about`, changeFrequency: 'monthly', priority: 0.8 },
...posts.map((p) => ({
url: `${baseUrl}/blog/${p.slug}`,
lastModified: p.updatedAt,
changeFrequency: 'weekly' as const,
priority: 0.7,
})),
];
}
force-dynamic нужен, чтобы sitemap не собирался во время сборки: тогда Next.js не пойдёт в базу на этапе build.
Проверка: откройте https://ваш-домен.ru/sitemap.xml — должен открыться XML со списком страниц.
3. Закрыть служебные страницы от индексации
Страницы с авторизацией и личными данными нельзя пускать в поисковики. В App Router целый раздел закрывается одной строкой в layout.tsx — все вложенные страницы получат noindex:
// src/app/(dashboard)/layout.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
robots: { index: false, follow: false },
};
Это закрывает /dashboard, /profile, /settings и всё, что внутри.
Для отдельной страницы — то же самое в её page.tsx.
Проверить, что страница закрыта: в браузере Ctrl+U → найдите <meta name="robots" content="noindex">. Или Google Search Console → «Проверка URL».
На RelaxDev технический адрес проекта проект.relaxdev.ru и адреса превью уже отдаются с noindex — дублей вашего сайта в выдаче они не создают.
4. Название сайта в выдаче
Над заголовком результата Google показывает название сайта. Если сайт его не сообщил, Google подставляет домен — а кириллический домен в виде xn--…. Название задаётся разметкой WebSite на главной и og:site_name:
// src/app/layout.tsx
export const metadata: Metadata = {
metadataBase: new URL('https://ваш-домен.ru'),
openGraph: { siteName: 'Название сайта' },
};
// src/app/page.tsx — внутри разметки главной
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'Название сайта',
alternateName: 'ваш-домен.ru',
url: 'https://ваш-домен.ru/',
}),
}}
/>
url должен совпадать с адресом главной в canonical. Google подхватит название при следующем обходе главной.
5. Подтверждение сайта
Самый простой способ в Next.js — метатеги через metadata, без файлов:
// src/app/layout.tsx
export const metadata: Metadata = {
verification: {
google: 'код-из-search-console',
yandex: 'код-из-вебмастера',
},
};
Если удобнее файлами — в Google Search Console и Яндекс Вебмастере выберите метод «HTML-файл», скачайте файлы и положите в public/:
public/
google123abc456def.html ← Google
yandex_12345abcdef.html ← Яндекс
Файлы из public/ доступны по корневому адресу автоматически: после деплоя https://ваш-домен.ru/google123abc456def.html откроется сразу. Закоммитьте, задеплойте и нажмите «Подтвердить» в панели каждого поисковика.
6. Яндекс Метрика
Счётчик — это не только аналитика: по опыту, с ним Яндекс находит и обходит новые страницы быстрее.
// src/app/layout.tsx
import Script from 'next/script';
// Внутри <body>:
<Script id="yandex-metrika" strategy="lazyOnload">
{`(function(m,e,t,r,i,k,a){
m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
k=e.createElement(t),a=e.getElementsByTagName(t)[0];
k.async=1;k.src=r;a.parentNode.insertBefore(k,a)
})(window,document,"script","https://mc.yandex.ru/metrika/tag.js","ym");
ym(XXXXXXXX,"init",{ clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true });`}
</Script>
Где XXXXXXXX — номер счётчика из metrika.yandex.ru. lazyOnload грузит счётчик после загрузки страницы и не отнимает баллы у PageSpeed. Не забудьте упомянуть Метрику в политике cookie.
7. Отправить sitemap в поисковики
Без этого поисковики могут неделями не находить новые страницы.
- Google Search Console: Индексирование → Файлы Sitemap → добавить
https://ваш-домен.ru/sitemap.xml→ «Отправить». - Яндекс Вебмастер: Индексирование → Файлы Sitemap → добавить
https://ваш-домен.ru/sitemap.xml.
8. Кириллический домен (.рф и другие)
Домен кухниостровский.рф в DNS и браузерах хранится как xn--b1albebcsjatkdjj4a.xn--p1ai — это один и тот же адрес. Что важно для SEO:
- Одна форма адреса везде: в
metadataBase,canonical, sitemap, robots и внутренних ссылках. Punycode (xn--…) понимают все роботы без исключения. - Название сайта в выдаче — обязательно разметка WebSite из раздела 4. Без неё Google покажет над заголовком
xn--…. - Яндекс показывает кириллические домены нормально. В Вебмастере есть «Регистр имени сайта»: можно задать вид
КухниОстровский.рф. - Ссылка, скопированная из выдачи или браузера, приходит в punycode — она рабочая, это та же страница.
- В панели RelaxDev домен можно вводить кириллицей: хранится он в punycode, показывается кириллицей, записи у регистратора те же.
Подробнее про записи, www и редиректы — в статье «Домены и DNS на RelaxDev».
Чек-лист
https://ваш-домен.ru/robots.txtоткрываетсяhttps://ваш-домен.ru/sitemap.xmlоткрывается с нужными страницами- Закрытые разделы (
/dashboard/,/admin/) имеютrobots: { index: false } - На главной есть разметка WebSite с названием сайта
- Сайт подтверждён в Google Search Console и Яндекс Вебмастере
- Счётчик Метрики установлен
- Sitemap отправлен в обе панели
- Для домена выбран один вариант — с www или без — второй перенаправляется на него
Сроки: обычно Google — от нескольких дней до недели, Яндекс — несколько дней.
Читайте также
- Год на Vercel и один вечер переезда: bazariara.ge стал быстрее и снова открывается в России — 100 из 100 в PageSpeed после переезда
- Та же история для SEO-специалистов — на vc.ru
- Превью-окружения: как проверять ветку, не ломая продакшн
Вопросы — пишите в комментарии 👇
Читайте также

Как подключить свой домен к проекту на RelaxDev, какие записи нужны, чем поддомен отличается от домена, как…

Bazari Ara — интернет-магазин грузинских продуктов, подарков и туристического снаряжения в Тбилиси. Next.js…

Мы разрабатываем — систему, в которой служба доставки видит заказы, курьеров, маршруты и финансы в одном…
Комментарии (0)
Ответить без регистрации