Как создать многоязычные карты сайта в 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

Индекс карты сайта, в котором перечислены все ваши карты сайта, позволяет поисковым системам находить все языковые карты сайта из одной точки входа. Поисковики будут сканировать индекс и автоматически переходить по ссылкам на каждую языковую карту сайта.