
Алексей Баранов
Добавляем sitemap.xml в Next.js приложение
Важным элементом SEO-оптимизации является наличие файла sitemap.xml. В этой статье вы узнаете, что такое sitemap.xml и как добавить его в свое приложение на Next.js.
Что такое sitemap.xml?
Sitemap.xml - это файл формата Sitemaps XML format, который сообщает поисковым системам (например Google или Yandex), какие страницы есть на вашем сайте и как часто они обновляются.
Этот файл должен находиться в корневой папке вашего сайта, и обычно доступен по адресу:
домен.зона/sitemap.xml
Например, sitemap.xml этого блога лежит по адресу https://alexeybaranov.dev/sitemap.xml и выглядит следующим образом:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://alexeybaranov.dev/</loc>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
...
</urlset>
Более подробную информацию о том как как поисковые системы обрабатывают файлы sitemap.xml можно найти в справке от Яндекса или документации Google.
Первый способ: Добавляем статический файл
Первый способ - очень простой. Next.js из коробки умеет отдавать статические файлы, например изображения, добавленные в папку public в корне проекта.
Этот же подход можно использовать для добавления файла sitemap.xml. Всё что необходимо сделать - добавить файл в папку public.
Подробнее про работу со статикой и папку public можно почитать в официальной документации Next.js.
Как видите, способ действительно очень простой, но подойдёт он вам только в случае, если у вас небольшой сайт, с редко меняющимся содержимым. В противном случае лучше прибегнуть к динамической генерации sitemap.xml.
Альтернативный способ добавления статического файла
Начиная с версии 13.3 Next.js умеет корректно обрабатывать статический файл sitemap.xml лежащий в корне папки app.
Подробнее в документации.
Второй способ: Динамическая генерация sitemap.xml
Для того чтобы динамически создавать файл sitemap.xml необходимо в папку app добавить файл robots.js или robots.ts, который будет возвращать объект типа MetadataRoute.Sitemap.
import { MetadataRoute } from "next";
import { URL_BASE } from "@/lib/constants";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: `${URL_BASE}/`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.7,
},
{
url: `${URL_BASE}/about/`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.7,
},
{
url: `${URL_BASE}/posts/`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.7,
},
];
}
Данный код сгенерирует файл со следующим содержимым:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://alexeybaranov.dev/</loc>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://alexeybaranov.dev/about/</loc>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://alexeybaranov.dev/posts/</loc>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>
Генерация Image Sitemaps
Так же, начиная с 15 версии в Next.js есть встроенная возможность генерировать Image Sitemaps. Для этого надо всего лишь добавить свойство images (см. спецификацию) к странице.
import { MetadataRoute } from "next";
import { URL_BASE } from "@/lib/constants";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: `${URL_BASE}/`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.7,
images: ["https://alexeybaranov.dev/assets/blog/authors/avatar.webp"],
},
];
}
В результате получим следующий файл:
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
>
<url>
<loc>https://alexeybaranov.dev/</loc>
<image:image>
<image:loc>https://alexeybaranov.dev/assets/blog/authors/avatar.webp</image:loc>
</image:image>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>
Генерация Video Sitemaps
Так же, начиная с 15 версии в Next.js есть встроенная возможность генерировать Video Sitemaps. Для этого надо всего лишь добавить свойство videos (см. спецификацию) к странице.
import { MetadataRoute } from "next";
import { URL_BASE } from "@/lib/constants";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: `${URL_BASE}/posts/yandex-gpt-intro/`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.7,
videos: [
{
title: "Название видео",
thumbnail_loc:
"https://alexeybaranov.dev/assets/blog/yandex-gpt-intro/cover.webp",
description: "Это описание видео",
},
],
},
];
}
В результате получим следующий файл:
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"
>
<url>
<loc>https://alexeybaranov.dev/posts/yandex-gpt-intro/</loc>
<video:video>
<video:title>Название видео</video:title>
<video:thumbnail_loc>https://alexeybaranov.dev/assets/blog/yandex-gpt-intro/cover.webp</video:thumbnail_loc>
<video:description>Это описание видео</video:description>
</video:video>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>
Генерация локализованных Sitemaps
В Next.js есть встроенная возможность добавлять ссылки на версии страниц на другом языке при генерации sitemap.xml. Для этого надо всего лишь добавить свойство alternates (см. спецификацию) к странице.
import { MetadataRoute } from "next";
import { URL_BASE } from "@/lib/constants";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: `${URL_BASE}/`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.7,
alternates: {
languages: {
en: `${URL_BASE}/en/`,
fr: `${URL_BASE}/fr/`,
},
},
},
];
}
В результате получим следующий файл:
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
>
<url>
<loc>https://alexeybaranov.dev/</loc>
<xhtml:link
rel="alternate"
hreflang="en"
href="https://alexeybaranov.dev/en/"/>
<xhtml:link
rel="alternate"
hreflang="fr"
href="https://alexeybaranov.dev/fr/"/>
<lastmod>2025-03-13T12:07:00.337Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>
Спецификация MetadataRoute.Sitemap
Вот полная спецификация MetadataRoute.Sitemap, взятая из официального репозитория на Github.
type Sitemap = Array<{
url: string;
lastModified?: string | Date | undefined;
changeFrequency?:
| "always"
| "hourly"
| "daily"
| "weekly"
| "monthly"
| "yearly"
| "never"
| undefined;
priority?: number | undefined;
alternates?:
| {
languages?: Languages<string> | undefined;
}
| undefined;
images?: string[] | undefined;
videos?: Videos[] | undefined;
}>;
export type Videos = {
title: string;
thumbnail_loc: string;
description: string;
content_loc?: string | undefined;
player_loc?: string | undefined;
duration?: number | undefined;
expiration_date?: Date | string | undefined;
rating?: number | undefined;
view_count?: number | undefined;
publication_date?: Date | string | undefined;
family_friendly?: "yes" | "no" | undefined;
restriction?: Restriction | undefined;
platform?: Restriction | undefined;
requires_subscription?: "yes" | "no" | undefined;
uploader?:
| {
info?: string | undefined;
content?: string | undefined;
}
| undefined;
live?: "yes" | "no" | undefined;
tag?: string | undefined;
};
Альтернативные решения
Так же есть несколько альтернативных решений для генерации sitemap.xml в виде npm-пакетов. Например пакет next-sitemap.
Бонус: Валидация sitemap.xml
Для того чтобы удостовериться что содержимое sitemap.xml валидно и будет работать как и задумано, можно воспользоваться несколькими бесплатными инструментами:
На этом всё! 🎉
Подписывайтесь на мой Youtube канал, Telegram и на сообщество Вконтакте 🙂



