Как создать многоязычные карты сайта в React Router v7
Организуйте карты сайта по языкам для масштабирования
Проблема
Карты сайта помогают поисковым системам находить и индексировать все страницы сайта. На многоязычном сайте с сотнями или тысячами страниц на каждом языке карты сайта быстро становятся огромными. Один файл со всеми URL для всех языков становится неудобным, может превысить лимиты в 50 000 URL или 50 МБ, и усложняет обслуживание. Если вы меняете структуру на одном языке, приходится пересоздавать и проверять весь файл. Такой подход не масштабируется по мере роста сайта.
Решение
Разделите карты сайта на иерархию: создайте индексную карту сайта верхнего уровня, которая ссылается на отдельные карты сайта для каждого языка. Для каждого языка создаётся свой файл карты сайта только с URL этого языка. Индексный файл выступает в роли каталога, указывая местоположение каждой языковой карты сайта. Это делает отдельные файлы компактными, позволяет обновлять каждый язык независимо и хорошо масштабируется при добавлении новых языков или страниц. Поисковые системы сначала обходят индекс, а затем переходят по ссылкам на карты сайта каждого языка.
Шаги
1. Создайте маршрут для индексной карты сайта
Создайте ресурсный маршрут, который возвращает XML-ответ со списком всех языковых карт сайта.
import type { Route } from "./+types/sitemap";
const LOCALES = ["en", "es", "fr", "de"];
export function loader({ request }: Route.LoaderArgs) {
const { origin } = new URL(request.url);
const sitemapIndex = `<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${LOCALES.map(locale => ` <sitemap>
<loc>${origin}/sitemap-${locale}.xml</loc>
</sitemap>`).join("
")}
</sitemapindex>`;
return new Response(sitemapIndex, {
headers: {
"Content-Type": "application/xml",
},
});
}
Этот маршрут работает как API-эндпоинт, возвращая XML-ответ. В индексе указывается по одной карте сайта на каждый язык, поэтому добавить или удалить язык можно, просто изменив массив LOCALES.
2. Создайте маршруты для языковых карт сайта
Определите ресурсный маршрут с динамическим сегментом, чтобы генерировать отдельные карты сайта для каждого языка.
import type { Route } from "./+types/sitemap.$locale";
export async function loader({ params }: Route.LoaderArgs) {
const locale = params.locale;
const urls = await getUrlsForLocale(locale);
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(url => ` <url>
<loc>${url}</loc>
</url>`).join("
")}
</urlset>`;
return new Response(sitemap, {
headers: {
"Content-Type": "application/xml",
},
});
}
async function getUrlsForLocale(locale: string): Promise<string[]> {
return [];
}
Динамический сегмент в пути маршрута разбирается и передаётся как params.locale. В каждой языковой карте сайта содержатся только URL-адреса для этой конкретной локали.
3. Получите страницы для каждого языка
Реализуйте вспомогательную функцию для получения всех страниц для заданной локали из вашего источника данных.
async function getUrlsForLocale(locale: string): Promise<string[]> {
const pages = await db.pages.findMany({
where: { locale, published: true },
select: { slug: true },
});
return pages.map((page) => `https://example.com/${locale}/${page.slug}`);
}
Эта функция делает запрос к вашей базе данных или источнику контента для опубликованных страниц на нужном языке и формирует полные URL-адреса. Настройте запрос и структуру URL под ваше приложение.
4. Зарегистрируйте маршруты карты сайта
Добавьте маршруты карты сайта в файл конфигурации маршрутов.
import { type RouteConfig, route } from "@react-router/dev/routes";
export default [
route("sitemap.xml", "./routes/sitemap.tsx"),
route("sitemap-:locale.xml", "./routes/sitemap.$locale.tsx"),
] satisfies RouteConfig;
У каждого маршрута есть шаблон URL для сопоставления и путь к файлу модуля маршрута. Индексный маршрут отвечает по адресу /sitemap.xml, а языковые маршруты — по /sitemap-en.xml, /sitemap-es.xml и так далее.
5. Добавьте индекс карты сайта в robots.txt
Укажите поисковым системам на индекс карты сайта в файле robots.txt в корне вашей публичной директории.
User-agent: *
Allow: /
Sitemap: https://example.com/sitemap.xml
Индекс карты сайта, в котором перечислены все ваши карты сайта, позволяет поисковым системам находить все языковые карты сайта из одной точки входа. Поисковики будут сканировать индекс и автоматически переходить по ссылкам на каждую языковую карту сайта.