Файл sitemap для Next.js — один из обязательных элементов технической оптимизации. С помощью карты сайта поисковые роботы быстрее находят и индексируют новые страницы, особенно если сайт содержит тысячи динамических маршрутов. В Next.js начиная с 13-й версии и App Router появился встроенный генератор, способный формировать sitemap.xml без сторонних пакетов. Для проектов на старом Pages Router или для расширенных требований многие разработчики используют next-sitemap. По состоянию на 2026 год оба подхода остаются актуальными, но встроенный механизм в Next.js 15 уже покрывает большинство сценариев.
В этом материале мы разберём, как создать sitemap для Next.js сайта всеми доступными способами: от простого статического до разбиения на множество файлов и интеграции с протоколом IndexNow. Все примеры ориентированы на App Router, но для обратной совместимости рассмотрим и альтернативы. Материал дополняют обзоры общих принципов SEO в Next.js — читайте статьи «Next.js — SEO и индексация» и «SEO-оптимизация Next.js сайта».
Встроенный sitemap в Next.js (App Router)
С версии Next.js 13.4, когда стабилизировался App Router, генерация sitemap стала возможной без дополнительных зависимостей. Достаточно создать файл app/sitemap.ts, экспортирующий функцию с именем sitemap. Фреймворк автоматически обнаруживает этот файл и отдаёт по адресу /sitemap.xml с корректным Content-Type. Формат возвращаемых данных описан в MetadataRoute.Sitemap — массив объектов, каждый из которых представляет одну запись sitemap.
Использование встроенного механизма даёт ряд преимуществ:
- Никаких внешних библиотек — меньше зависимостей, проще обновления.
- Глубокая интеграция с file-based маршрутизацией App Router.
- Поддержка различных режимов сборки: статический билд, динамические данные, разбиение на файлы.
- Автоматическая ревалидация для динамических sitemap через
export const revalidate.
Статический sitemap
Если сайт содержит фиксированный набор страниц, карту сайта можно задать простым экспортом массива. Это подходит для лендингов, визиток, документации и любых проектов с маршрутами, которые не зависят от внешних источников данных.
import type { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://example.com',
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 1,
},
{
url: 'https://example.com/about',
lastModified: new Date('2026-01-15'),
changeFrequency: 'yearly',
priority: 0.8,
},
{
url: 'https://example.com/contacts',
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.5,
},
]
}
Поле lastModified принимает объект Date или строку в формате ISO 8601. Поисковые системы учитывают его для определения даты последнего изменения страницы. Атрибуты changeFrequency и priority носят рекомендательный характер: Google игнорирует priority, а Яндекс учитывает оба параметра при планировании обходов.
При статическом билде Next.js вызовет функцию sitemap() один раз во время next build и сохранит результат как статический XML. Это самый быстрый вариант — sitemap не нагружает сервер при каждом запросе.
Динамический sitemap
Проекты с постами блога, товарами каталога или любыми сущностями из CMS требуют, чтобы sitemap автоматически включал все актуальные URL. Функция sitemap() может быть асинхронной и запрашивать данные из любого источника: headless CMS, базы данных через API, файловой системы (локальные Markdown/MDX), Prisma, Contentful, Strapi и т.п.
Практический пример с загрузкой статей из внешнего API:
import type { MetadataRoute } from 'next'
async function getAllPosts() {
const res = await fetch('https://cms.example.com/api/posts', {
next: { revalidate: 3600 }, // ISR-кэш на час
})
if (!res.ok) throw new Error('Ошибка загрузки постов')
return res.json()
}
export default async function sitemap(): Promise {
const baseUrl = 'https://example.com'
const posts = await getAllPosts()
const blogUrls = posts.map((post) => ({
url: `${baseUrl}/blog/${post.slug}`,
lastModified: new Date(post.updatedAt),
changeFrequency: 'weekly' as const,
priority: 0.7,
}))
return [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 1,
},
...blogUrls,
]
}
В этом примере getAllPosts отправляет запрос к API. Next.js автоматически применяет кэширование на основе значения revalidate или заголовков ответа. Если во время сборки данные получить не удалось, лучше предусмотреть запасной вариант, чтобы sitemap не стал пустым. Например, вернуть хотя бы основные статические страницы.
На проекте с каталогом из 12000 товаров мы использовали динамический sitemap с пагинированным запросом к API и сохранением lastModified из поля updatedAt. При каждом билде Next.js перебирает все товары и формирует записи. Для такого объёма данных может потребоваться увеличение лимита памяти сборки, но на Vercel Pro тариф в 6 ГБ потянет 30 000 URL без проблем. Если товаров больше — переходите к множественным sitemap.
Множественные sitemaps (generateSitemaps)
Стандарт sitemap ограничивает размер одного файла 50 000 URL и 50 МБ в несжатом виде. Когда сайт переваливает за этот порог, нужно разбить карту на несколько файлов и создать sitemap index. Next.js делает это автоматически при использовании функции generateSitemaps.
generateSitemaps возвращает массив идентификаторов (например, номера страниц). Для каждого идентификатора Next.js вызовет функцию sitemap({ id }) с соответствующим аргументом, ожидая массив URL. Результатом станут маршруты вида /sitemap/0.xml, /sitemap/1.xml и общий индекс по адресу /sitemap.xml.
import type { MetadataRoute } from 'next'
async function fetchProducts(page: number, limit: number) {
const res = await fetch(
`https://cms.example.com/api/products?page=${page}&limit=${limit}`
)
return res.json()
}
export async function generateSitemaps() {
// Допустим, всего 125 000 товаров, разбиваем по 10 000
return [
{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 },
{ id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }, { id: 9 },
{ id: 10 }, { id: 11 }, { id: 12 },
]
}
export default async function sitemap({ id }: { id: number }): Promise {
const limit = 10000
const page = id // id = 0 -> page 1
const products = await fetchProducts(page, limit)
return products.map((product) => ({
url: `https://example.com/product/${product.slug}`,
lastModified: new Date(product.updatedAt),
changeFrequency: 'weekly' as const,
priority: 0.6,
}))
}
Идентификаторами могут быть строки или числа. Для постов блога, разбитых по годам, можно вернуть массив ['2025', '2026'], а внутри sitemap({ id }) запросить статьи за соответствующий год. Количество записей в каждой части не обязано быть строго одинаковым, но старайтесь не превышать лимит в 50 тыс.
При индексации поисковые роботы сначала читают индекс, затем переходят по каждой части. Такой подход полностью соответствует спецификации sitemaps.org и корректно обрабатывается Яндексом, Google и Bing. Важно, чтобы все файлы были доступны по HTTPS и возвращали статус 200.
Пакет next-sitemap
До появления встроенного генератора стандартным выбором в сообществе Next.js был пакет next-sitemap. Он до сих пор используется на многих проектах, особенно построенных на Pages Router, а также для дополнительной гибкости, которую App Router «из коробки» не даёт. В частности, next-sitemap умеет:
- Сканировать папку
pagesи формировать URL автоматически. - Применять transform-функцию для каждой записи.
- Генерировать
robots.txt. - Исключать определённые пути через конфигурацию.
- Создавать серверный sitemap для полностью динамического контента.
Установка и базовая настройка
Для начала установите пакет как dev-зависимость:
npm install --save-dev next-sitemap
Затем создайте в корне проекта файл next-sitemap.config.js:
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
exclude: ['/admin/*', '/dashboard/*', '/api/*'],
robotsTxtOptions: {
additionalSitemaps: [
'https://example.com/server-sitemap.xml',
'https://example.com/sitemap-images.xml',
],
},
changefreq: 'daily',
priority: 0.7,
sitemapSize: 7000,
transform: async (config, path) => {
// кастомная логика для отдельных маршрутов
if (path === '/') {
return {
loc: path,
changefreq: 'daily',
priority: 1.0,
lastmod: new Date().toISOString(),
}
}
// для остальных используем значения по умолчанию
return {
loc: path,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
}
},
}
Основные параметры конфигурации:
| siteUrl | Базовый URL сайта, включая протокол. |
| generateRobotsTxt | Создавать ли robots.txt автоматически. |
| exclude | Массив glob-паттернов для исключения из sitemap. |
| sitemapSize | Количество URL в одном файле (по умолчанию 50000). |
| changefreq / priority | Значения по умолчанию для всех URL. |
| additionalSitemaps | Ссылки на дополнительные файлы в sitemap index. |
| transform | Функция для изменения данных каждой записи. |
Чтобы запускать генерацию после сборки, добавьте скрипт в package.json:
{
"scripts": {
"build": "next build && next-sitemap"
}
}
При запуске npm run build пакет сканирует сгенерированные статические страницы и создаёт файлы public/sitemap.xml (индекс) и public/sitemap-0.xml (первая часть). Если проект использует SSG, все маршруты из функций getStaticPaths попадают в sitemap автоматически. Это удобно для блогов с Markdown, где контент меняется нечасто.
Серверный sitemap для динамического контента
Если контент полностью динамический и не порождает статические страницы на этапе сборки (например, товары Subway или новости, которые меняются каждую минуту), статическая генерация не подходит. next-sitemap предоставляет метод getServerSideSitemap для создания карты сайта на лету при обращении к специальному маршруту.
Создайте файл в pages/server-sitemap.xml/index.tsx (для проектов на Pages Router). Этот маршрут будет обрабатывать запросы и отдавать XML с реальными данными из базы или API.
import { getServerSideSitemap, ISitemapField } from 'next-sitemap'
export const getServerSideProps = async (ctx) => {
const response = await fetch('https://cms.example.com/api/dynamic-items')
const items = await response.json()
const fields: ISitemapField[] = items.map((item) => ({
loc: `https://example.com/dynamic/${item.slug}`,
lastmod: item.updatedAt,
changefreq: 'hourly',
priority: 0.8,
}))
return getServerSideSitemap(ctx, fields)
}
export default function Sitemap() {
// компонент не рендерится, используется только getServerSideProps
}
В конфигурации next-sitemap.config.js укажите этот маршрут в additionalSitemaps, чтобы он был включён в индекс.
Для App Router аналогичный подход требует реализации API-роута с ручной генерацией XML. Например, в app/server-sitemap.xml/route.ts можно вернуть сформированный XML. Встроенный механизм Next.js тоже позволяет сделать это динамически, но иногда требуется внешний sitemap, генерируемый отдельным микросервисом.
Генерация robots.txt через app/robots.ts
Файл robots.txt сообщает роботам, какие разделы сайта можно индексировать, и указывает путь к sitemap. В App Router можно создать app/robots.ts, экспортирующий функцию robots(). Next.js автоматически обслуживает его по адресу /robots.txt.
import type { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: ['/admin/', '/api/', '/dashboard/'],
},
sitemap: 'https://example.com/sitemap.xml',
}
}
Поле sitemap может быть строкой или массивом ссылок, если у вас несколько sitemap-индексов. Если вы используете пакет next-sitemap с generateRobotsTxt: true, он переопределит встроенный robots.ts, поэтому лучше выбрать что-то одно.
Не забудьте, что robots.txt должен быть доступен по корню домена без перенаправлений. Next.js отдаст его с правильным Content-Type и статусом 200, даже если у вас используется Static Export — файл будет сгенерирован в папке out.
Автоматизация генерации sitemap при деплое
Чтобы sitemap не устаревал, его генерацию необходимо встроить в CI/CD пайплайн. Для проектов, использующих встроенный механизм App Router, это не требует дополнительных действий: при билде Next.js выполнит функции sitemap и сохранит результат. Даже динамический sitemap с выборкой данных кешируется и перестраивается при каждом билде.
Если используется next-sitemap, скрипт next-sitemap запускается после next build. На Vercel билд выполняется командой из package.json, которую вы можете свободно менять. Например:
"scripts": {
"build": "next build && next-sitemap && node scripts/indexnow.js"
}
На Netlify необходимо указать команду билда в настройках деплоя, аналогично: npm run build. После деплоя публичная директория со всеми статическими файлами заливается в CDN, и sitemaps становятся доступны для поисковиков.
Для сайтов с частым обновлением контента (например, маркетплейс с тысячами позиций) запуска билда может быть недостаточно. Тогда стоит перейти на динамический sitemap с кэшированием или настроить периодический вызов GET /sitemap.xml с передачей Cache-Control: no-cache, чтобы вызвать регенерацию. На платформах типа Vercel можно использовать cron jobs, которые «прогревают» маршруты раз в час.
Интеграция с IndexNow для ускоренной индексации
После публикации нового контента или изменения старых страниц полезно уведомить поисковые системы напрямую. С 2022 года Яндекс, Bing и Naver поддерживают протокол IndexNow, а Google с 2025 года тестирует экспериментальную поддержку. Протокол позволяет мгновенно отправить список обновлённых URL без ожидания запланированного переобхода.
Интегрировать IndexNow в Next.js можно разными способами:
- В скрипте после билда (например,
scripts/indexnow.js) читать сгенерированный sitemap, выделять изменённые URL и отправлять POST-запрос к API IndexNow. - Использовать вебхук CMS: при создании/обновлении контента CMS отправляет запрос к вашему API, который вызывает IndexNow.
- С помощью сервисов-посредников, таких как Index-Now.ru, которые автоматизируют пингование всех поддерживаемых систем и предоставляют панель мониторинга.
Пример простого скрипта для ручного пингования:
const https = require('https');
const key = 'ваш_ключ_indexnow';
const keyLocation = 'https://example.com/indexnow-key.txt';
const urlList = [
'https://example.com/new-page',
'https://example.com/updated-page',
];
const data = JSON.stringify({
host: 'example.com',
key: key,
keyLocation: keyLocation,
urlList: urlList,
});
const req = https.request('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
}, (res) => {
console.log('IndexNow response:', res.statusCode);
});
req.write(data);
req.end();
Ключ IndexNow должен быть доступен по адресу https://example.com/indexnow-key.txt. Вы можете добавить этот файл в папку public проекта Next.js. После первого уведомления поисковики начинают учитывать изменения практически сразу — по нашим замерам, время появления новых страниц в индексе Яндекса сокращается с часов до нескольких минут.
Более комплексное решение с историей отправок и автоматическим мониторингом предоставляет сервис Index-Now.ru. Он берёт на себя отправку в Яндекс, Google, Bing и другие поддерживаемые системы, а также проверяет статус индексации отправленных URL. В контексте Next.js вы можете просто отправлять запрос к их API после каждого деплоя или добавления контента.
Дополнительные технические аспекты
lastmod, changefreq, priority — что и как указывать
Эти три поля влияют на то, как часто поисковики переиндексируют страницы. Хотя Google заявляет, что игнорирует priority и changefreq, Яндекс активно использует их в алгоритмах планирования обхода. Поэтому для русскоязычной аудитории эти атрибуты важны.
lastmod— дата последнего достоверного изменения контента. Указывайте реальное время модификации, а не текущую дату при каждой сборке. Если страница не менялась годами, дата должна быть старой. Мы в своих проектах берём даты из полей «updatedAt» в CMS.changefreq— частота обновлений по субъективной оценке. Допустимые значения:always, hourly, daily, weekly, monthly, yearly, never. Для ленты новостей ставьтеhourly, для статьи —monthlyилиyearly.priority— число от 0.0 до 1.0, указывающее относительную важность страницы на сайте. Главная — 1.0, второстепенные — 0.5. Не пытайтесь поднять приоритет всех страниц до максимума: поисковик воспринимает значение относительно других страниц вашего же сайта.
В Next.js встроенный sitemap поддерживает эти поля через соответствующие ключи объекта. В next-sitemap они глобально настраиваются в конфиге и могут быть переопределены в transform. Независимо от инструмента, избегайте «мусора»: не заполняйте priority везде одинаково, лучше вовсе опустите это поле, если не уверены.
Добавление изображений и видео в sitemap
Sitemap может содержать дополнительную информацию об изображениях и видео, которые размещены на страницах. Для интернет-магазинов, галерей и видеохостингов эта разметка критична, потому что помогает картинкам и роликам попасть в Google Images, Google Video и Яндекс.Картинки.
Встроенный sitemap Next.js позволяет добавить изображения, передав массив images в объекте записи:
import type { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://example.com/product/123',
lastModified: new Date(),
images: [
{
url: 'https://cdn.example.com/product-123-main.jpg',
caption: 'Основное фото товара',
title: 'Вид спереди',
geoLocation: 'Москва',
},
{
url: 'https://cdn.example.com/product-123-side.jpg',
},
],
},
]
}
Аналогично можно включить ролики, но официального типа videos в MetadataRoute.Sitemap пока нет. Для видео используйте next-sitemap с кастомной трансформацией, где добавляете соответствующие XML-элементы. Либо генерируйте видео-sitemap отдельным файлом по спецификации Google.
// пример transform для видео
transform: async (config, path) => {
if (path.startsWith('/video/')) {
return {
loc: path,
lastmod: ...,
video: [
{
thumbnail_loc: 'https://img.example.com/thumb.jpg',
title: 'Заголовок видео',
description: 'Описание',
content_loc: 'https://video.example.com/content.mp4',
player_loc: 'https://example.com/player?video=123',
duration: 120,
},
],
}
}
}
При использовании изображений учитывайте, что они должны быть доступны для индексации (не заблокированы robots.txt и не закрыты от гуглобота). Также лучше использовать абсолютные URL.
Мультиязычные сайты и атрибут rel=alternate
Если сайт поддерживает несколько языков или регионов, важно сообщить поисковикам о взаимосвязях страниц. Для этого в sitemap добавляется указание alternates — ссылки на альтернативные версии с атрибутом hreflang. Next.js встроенный sitemap поддерживает это поле нативно.
{
url: 'https://example.com/en/about',
lastModified: new Date(),
alternates: {
languages: {
'de': 'https://example.com/de/about',
'fr': 'https://example.com/fr/about',
'es': 'https://example.com/es/about',
},
},
}
Next.js автоматически добавляет канонический URL для языка по умолчанию. В примере выше английская страница будет считаться канонической для группы. Не забудьте, что для корректного ранжирования необходимо также прописать теги hreflang непосредственно в HTML каждой страницы — через metadata.alternates. Sitemap лишь дополняет информацию.
Для крупных мультиязычных магазинов мы вставляем ссылки на все существующие локали, предварительно проверив наличие переведённой страницы. Отсутствие одного из языков в альтернатах не критично, но лучше перечислить только реально существующие URL, чтобы избежать 404.
Кэширование динамического sitemap
Динамический sitemap, который делает запросы к базе или внешнему API, может подвергаться высокой нагрузке, если роботы часто его запрашивают. К счастью, Next.js позволяет управлять кэшем через переменную revalidate или заголовки ответа. Добавьте в app/sitemap.ts:
export const revalidate = 3600 // пересоздавать sitemap не чаще раза в час
Теперь Next.js будет отдавать кешированный XML и перестраивать его в фоне раз в час. Это снижает нагрузку на источники данных и ускоряет ответ для роботов. Учтите, что при использовании ISR максимально допустимое значение revalidate — 30 дней. Если контент меняется крайне редко, можно выставить 86400 (сутки).
Для next-sitemap при использовании серверного sitemap через getServerSideSitemap можно добавить заголовки кэша прямо в запросе:
ctx.res.setHeader('Cache-Control', 'public, s-maxage=3600')
Кроме того, многие CDN (Cloudflare, Vercel Edge Network) кэшируют sitemap по умолчанию при наличии заголовков. Это дополнительная линия защиты.
Учёт ISR-страниц при формировании sitemap
Incremental Static Regeneration позволяет добавлять новые страницы без полной пересборки сайта. Однако sitemap, сгенерированный во время билда, о новых ISR-маршрутах ничего не знает. Решение зависит от того, как именно создаются ISR-страницы:
- Если ISR-страницы появляются только после доопределения статического параметра (on-demand revalidation с новым путём), в sitemap они автоматически не попадают до следующего билда. В таких случаях нужно дополнить встроенный sitemap логикой, которая через API CMS или базы данных получает полный список всех допустимых slug и включает их. Таким образом, при билде вы получите актуальный перечень.
- Если ISR-страницы генерируются из данных, которые уже известны на момент билда (например, из списка постов), то они будут включены в sitemap как обычные динамические маршруты.
- Для полностью динамических ISR-страниц без предопределённых путей имеет смысл перейти на серверный sitemap (через
next-sitemapgetServerSideSitemap или аналогичный API-роут), который при обращении актуализирует список на лету.
В одном из проектов с фильтрами (тысячи комбинаций) мы исключили ISR-страницы из sitemap, потому что они не являются самостоятельными посадочными страницами. Вместо этого мы индексировали только «канонические» URL, а ISR-варианты помечали noindex через метаданные. Так мы избежали дублирования контента и использования краулерного бюджета впустую.
Сравнение подходов: встроенный sitemap vs next-sitemap
Для выбора подходящего инструмента приведём сравнение ключевых возможностей.
| Функция | Встроенный sitemap (App Router) | next-sitemap |
|---|---|---|
| Поддержка Pages Router | Нет | Да |
| Статическая генерация | Да | Да |
| Динамические данные (async) | Да | Да (transform/серверный) |
| Разбиение на файлы | Да (generateSitemaps) | Да (sitemapSize, индекс) |
| Автоматический robots.txt | Да (app/robots.ts) | Да (опционально) |
| Изображения и видео | Изображения — да, видео — нет | Да (кастомная трансформация) |
| hreflang (мультиязычность) | Да (alternates) | Да (через transform) |
| Исключение URL | Не реализуется самим sitemap, можно не включать в массив | exclude паттерны |
| Серверный sitemap по запросу | Только экспортируя API-роут отдельно | Встроенная поддержка |
| Настройка из коробки | Минимальная, без зависимостей | Требует файла конфигурации и скрипта |
Если проект построен на App Router и не нуждается в видео или сложной пост-обработке каждой записи, встроенного sitemap более чем достаточно. Пакет next-sitemap оправдан, когда используется Pages Router, либо требуется автоматическое сканирование статической сборки без ручного перечисления всех URL, либо нужны продвинутые сценарии видео-разметки и серверного формирования.
Типичные ошибки при создании sitemap в Next.js
На основе аудита нескольких десятков сайтов мы выделили повторяющиеся проблемы, которые мешают индексации:
- Дублирование URL из-за слеша на конце. Проверьте, что все URL в sitemap используют единый формат — либо все со слешем, либо без. Next.js не приводит к единству автоматически; если в роутере есть оба варианта, указывайте канонический.
- Включение страниц, которые отдают 404 или закрыты в robots.txt. Лучше исключать такие URL из sitemap, чтобы не тратить краулерный бюджет.
- Превышение лимита в 50 000 URL в одном файле. Next.js с generateSitemaps предотвращает это, но при ручной генерации без разбивки вы рискуете тем, что поисковик проигнорирует лишние записи.
- Некорректный lastmod. Указание текущей даты для всех страниц при каждом билде вводит роботов в заблуждение — они считают, что все страницы изменились, и переиндексируют даже те, что не менялись годами. Такой «шум» снижает доверие к sitemap.
- Забытое кэширование. Динамический sitemap без revalidate может нагружать сервер, а также опаздывать с обновлениями, если кэш слишком долгий. Настройте разумный баланс.
Отдельно стоит упомянуть ситуацию с ISR: если вы включаете все комбинации параметров как отдельные URL в sitemap, но при этом они не несут уникального контента, поисковик может съесть краулерный бюджет и не дойти до действительно важных страниц. Анализируйте каждый URL с точки зрения пользы для индексации.
В процессе настройки sitemap для Next.js сайта полезно изучить полный цикл SEO-работ. В статьях «Next.js — SEO и индексация» и «SEO-оптимизация Next.js сайта» рассмотрены все аспекты от мета-тегов до Core Web Vitals.
Частые вопросы
Как часто нужно обновлять sitemap для динамического сайта?
Частота обновления самого файла sitemap не регламентирована. Главное, чтобы при каждом обращении поисковика он получал актуальные данные о датах изменения страниц. Для этого вы можете либо перегенерировать статический sitemap при каждом билде (если контент меняется преимущественно через донастройки и деплой), либо использовать динамический sitemap с кэшированием на 1–2 часа. Если поисковик замечает, что sitemap часто содержит устаревшие данные, он будет реже к нему обращаться.
Поддерживает ли Next.js sitemap для видео и изображений?
Встроенный sitemap Next.js поддерживает только изображения через поле images. Для видео необходимо либо применять пакет next-sitemap с кастомным transform, либо создавать отдельный файл видео-sitemap по спецификации Google. Рекомендуем генерировать видео-sitemap отдельно и указывать его в robots.txt через additionalSitemaps.
Как исключить страницу из sitemap, но оставить доступной для обхода?
Исключение из sitemap не запрещает индексацию — робот всё равно может найти страницу по ссылкам. Чтобы убрать URL из карты, достаточно не добавлять его в массив. В next-sitemap можно использовать параметр exclude или вернуть null в transform. Если же нужно запретить индексацию, используйте метатег <meta name="robots" content="noindex"> или заголовок X-Robots-Tag.
Как быть с UTM-метками и другими параметрами в URL?
Параметры, которые не меняют содержание страницы, не должны попадать в sitemap. Включаете только канонические URL. Дубли с параметрами всё равно могут быть обнаружены роботом, но sitemap должен ориентировать на основные адреса. Для предотвращения индексации дублей настройте канонические URL в <head> и, возможно, disallow для параметризованных путей в robots.txt.
Нужно ли отправлять sitemap в Google Search Console после каждого обновления?
Отправка sitemap в Search Console не обязательна при каждом изменении — достаточно один раз зарегистрировать файл. Поисковик будет обращаться к нему с той периодичностью, которую сочтёт нужной. Однако после серьёзных изменений на сайте (редизайн, миграция, запуск тысяч новых страниц) повторная отправка может ускорить переобход. Альтернативой, не требующей ручных действий, является использование IndexNow: API-уведомление позволяет сообщить об изменениях мгновенно.
Для автоматизации уведомлений через IndexNow воспользуйтесь сервисом Index-Now.ru, который избавляет от необходимости настраивать скрипты и следить за ответами разных поисковых систем. Подключив его к вашему Next.js проекту, вы обеспечите оперативное появление новых страниц в индексе Яндекса, Google и Bing сразу после деплоя.