Привет
Карта сайта важна для SEO, ведь она даёт поисковым системам дополнительное представление о сайте.
И в этом небольшом уроке я покажу, как создать карту сайта. Карта сайта представляет собой XML-документ, который традиционно доступен из корня сайта. Допустим, https://quasi-art.ru/sitemap.xml.
Требования
Невозможно создать универсальный код для создания карты сайта абсолютно для любого проекта. Всегда нужно учитывать структуру сайта, количество страниц и как их следует индексировать (частота индексирования, приоритет и пр). Но если понять основы, то можно создать карту сайта для любого проекта.
Так что в этом уроке я ориентируюсь на один свой проект. Я использую статическую генерацию, вложенность страниц минимальная.
Шаг 1
Для начала нужно создать файл sitemap.xml.js (или sitemap.xml.ts, если используете TypeScript) внутри каталога pages.
Таким образом, после сборки проекта становится доступной страница https://domain.ru/sitemap.xml.
Теперь поместим в созданный файл следующий код:
const Sitemap = () => {}
export const getServerSideProps = async ({ res }) => {
res.setHeader('Content-Type', 'text/xml')
res.write(`
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://domain.ru/works/3</loc>
<lastmod>2022-02-20T11:39:43.436Z</lastmod>
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://domain.ru/works/10</loc>
<lastmod>2022-02-20T11:39:43.436Z</lastmod>
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
<url>
</urlset>
`)
res.end()
return {
props: {},
}
}
export default Sitemap
Что здесь происходит:
- Объявлен компонент страницы — Sitemap.
- Объявлен метод getServerSideProps.
Метод getServerSideProps запускается для пре-рендера страницы при каждом запросе. В нём и будем описывать всю логику того, какие страницы и каким образом попадут на карту сайта.
Сейчас в этом методе карта сайта содержит не реальные данные, а хардкод.
Шаг 2
Настало время усложнить код.
По какому принципу всё будет работать: во время запроса страницы будет произведён сбор информации обо всех страницах (конкретно у меня — в массив объектов), которые нужно добавить в карту сайта. Затем на основании собранной информации будет собрана вёрстка. И эту вёрстку мы отрисуем в браузере.
import { fetchWorksData } from '@root/lib/works'
const Sitemap = () => {}
const getSitemapWrapperTemplate = (content: string) => {
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${content}
</urlset>
`
}
type Page = {
url: string;
changefreq: 'never' | 'yearly' | 'monthly' | 'weekly' | 'daily' | 'hourly' | 'always';
priority: '1.0';
}
export const getServerSideProps = async ({ res }) => {
const baseUrl = {
development: 'http://localhost:3000',
production: 'https://domain.ru',
}[process.env.NODE_ENV]
const pagesInfo: Page[] = []
const works = await fetchWorksData()
for (let i = 0; i < works.length; i++) {
pagesInfo.push({
url: `${baseUrl}/works/${works[i].id}`,
priority: '1.0',
changefreq: 'monthly',
})
}
const rows = pagesInfo
.map((pageInfo) => `
<url>
<loc>${pageInfo.url}</loc>
<lastmod>${new Date().toISOString()}</lastmod>
<changefreq>${pageInfo.changefreq}</changefreq>
<priority>${pageInfo.priority}</priority>
</url>
`)
.join('')
res.setHeader('Content-Type', 'text/xml')
res.write(getSitemapWrapperTemplate(rows))
res.end()
return {
props: {},
}
}
export default Sitemap
- В функцию getSitemapWrapperTemplate я вынес шаблон XML-документа. Цель: немного разгрузить функцию getServerSideProps.
- В переменной baseUrl содержится домен сайта, так как URI страниц в карте сайта должны быть абсолютными.
- Затем я объявляю массив pagesInfo.
- С помощью собственного метода fetchWorksData по API собираю информацию обо всех сущностях, которые на сайте имеют собственную страницу.
- Наполняю массив pagesInfo информацией о страницах.
- На основании этого массива формирую содержимое карты сайта: последовательно идущие теги url.
- Устанавливаю корректный тип содержимого для XML и записываю в объект ответа собранную в виде строки карту сайта.
Вывод
Я показал пример довольно частного случая, потому что всё зависит от многих параметров.
Можно в разный момент генерировать карту сайта (при сборке или при запросе), можно по-разному собирать информацию о страницах (из API или файловой системы) и так далее.
Но как отправная точка — сойдёт.