# gt-next: General Translation Next.js SDK: Алиасы локалей и SEO URL: https://generaltranslation.com/ru/docs/next/guides/locale-aliases.mdx --- title: Алиасы локалей и SEO description: Используйте пользовательские алиасы локалей для маршрутизации URL, сохраняя соответствие BCP 47 для поисковых систем --- Алиасы локалей позволяют использовать в URL пользовательские коды локалей (например, `/cn/` вместо `/zh/`), при этом SEO-метаданные будут соответствовать стандарту [BCP 47](https://www.w3.org/International/articles/language-tags/), которого ожидают поисковые системы. ## Зачем нужны алиасы? Коды локалей BCP 47, такие как `zh` (китайский) или `zh-Hant` (традиционный китайский), — это стандартный способ обозначать языки в вебе. Однако для путей URL вам могут понадобиться другие коды — из соображений брендинга, удобочитаемости или региональной специфики. Например, для китайской аудитории можно использовать `/cn/` вместо `/zh/`. GT поддерживает это через **пользовательское сопоставление** в `gt.config.json`. Алиас используется для маршрутизации и путей URL, а канонический код BCP 47 — везде, где он нужен поисковым системам. **Требование SEO:** Поисковые системы распознают только [коды локалей BCP 47](https://www.w3.org/International/articles/language-tags/). Если использовать нестандартные коды, например `cn`, в атрибутах `hreflang` или ``, поисковые системы будут игнорировать сигналы локали. ## Настройка ### Шаг 1: Настройте пользовательское сопоставление Добавьте запись `customMapping` в файл `gt.config.json` для каждого алиаса: ```json title="gt.config.json" { "defaultLocale": "en-US", "locales": ["en-US", "cn", "ja", "zh-Hant"], "customMapping": { "cn": { "code": "zh", "name": "Mandarin" } } } ``` Здесь `cn` — это алиас, используемый в URL и при маршрутизации через middleware, а `zh` — канонический код BCP 47. ### Шаг 2: Используйте middleware как обычно [middleware](/docs/next/guides/middleware) и динамический маршрут `[locale]` по умолчанию работают с вашими алиас-кодами. Пользователи, открывающие `/cn/about`, будут получать содержимое на китайском языке — для маршрутизации не нужна никакая специальная обработка. ## Соответствие BCP 47 для SEO Хотя алиасы без проблем работают для маршрутизации, есть три места, где вместо алиаса **обязательно** нужно использовать канонический код BCP 47: 1. Атрибут `lang` в теге `` 2. Теги альтернативных ссылок в метаданных страницы 3. Альтернативные записи в карте сайта GT предоставляет метод `resolveCanonicalLocale()` для преобразования алиасов обратно в коды BCP 47. Доступ к нему можно получить через `getGTClass` из `gt-next/server`: ```ts import { getGTClass } from 'gt-next/server'; const gtInstance = getGTClass(); const canonicalLocale = gtInstance.resolveCanonicalLocale('cn'); // Возвращает: "zh" ``` Для локалей без алиасов `resolveCanonicalLocale()` возвращает исходное значение без изменений: ```ts gtInstance.resolveCanonicalLocale('ja'); // "ja" gtInstance.resolveCanonicalLocale('en-US'); // "en-US" ``` ### 1. HTML-атрибут `lang` Атрибут `` сообщает браузерам и поисковым системам, на каком языке написана страница. Здесь должен быть указан корректный код BCP 47. В вашем root layout сначала определите локаль, а затем передайте её в тег ``: ```tsx title="app/[locale]/layout.tsx" import { getGTClass } from 'gt-next/server'; export default function RootLayout({ children, params, }: { children: React.ReactNode; params: { locale: string }; }) { const gtInstance = getGTClass(); const canonicalLocale = gtInstance.resolveCanonicalLocale(params.locale); return ( {children} ); } ``` Без этого страница по адресу `/cn/about` будет ошибочно рендерить ``, а поисковые системы не распознают такой язык. ### 2. Альтернативные метаданные Альтернативные ссылки сообщают поисковым системам, какие версии страницы доступны на других языках. Атрибут `hreflang` должен использовать коды BCP 47. ```tsx title="app/[locale]/layout.tsx" import type { Metadata } from 'next'; import { getGTClass } from 'gt-next/server'; export async function generateMetadata({ params, }: { params: { locale: string }; }): Promise { const gtInstance = getGTClass(); const locales = ['en-US', 'cn', 'ja', 'zh-Hant']; // Формируем alternates с каноническими кодами BCP 47 в качестве ключей const languages: Record = {}; for (const locale of locales) { const canonical = gtInstance.resolveCanonicalLocale(locale); languages[canonical] = `https://example.com/${locale}`; } // Добавляем x-default для локали по умолчанию languages['x-default'] = 'https://example.com'; return { alternates: { canonical: `https://example.com/${params.locale}`, languages, }, }; } ``` Это создаёт корректные теги `` в `head` страницы: ```html ``` Обратите внимание: в значениях `hreflang` используются канонические коды (`zh`, а не `cn`), а в URL-адресах `href` по-прежнему используются пути с алиасами (`/cn/`). ### 3. Альтернативные версии карты сайта Если вы используете [динамическую карту сайта](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap), примените тот же подход: ```ts title="app/sitemap.ts" import type { MetadataRoute } from 'next'; import { getGTClass } from 'gt-next/server'; export default function sitemap(): MetadataRoute.Sitemap { const gtInstance = getGTClass(); const locales = ['en-US', 'cn', 'ja', 'zh-Hant']; const baseUrl = 'https://example.com'; const pages = ['', '/about', '/pricing']; return pages.map((page) => { // Формируем языковые альтернативы с каноническими кодами const languages: Record = {}; for (const locale of locales) { const canonical = gtInstance.resolveCanonicalLocale(locale); languages[canonical] = `${baseUrl}/${locale}${page}`; } return { url: `${baseUrl}${page}`, lastModified: new Date(), alternates: { languages, }, }; }); } ``` Это создаёт XML-файл карты сайта с корректными атрибутами `hreflang`: ```xml https://example.com ``` ## Распространённые ошибки | Ошибка | Влияние | Исправление | | ------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------- | | Использование кода-алиаса в `` | Поисковые системы не могут определить язык страницы | Используйте `resolveCanonicalLocale()` для атрибута `lang` | | Использование кода-алиаса в `hreflang` | Поисковые системы игнорируют альтернативную ссылку | Используйте `resolveCanonicalLocale()` для значений `hreflang` | | Отсутствует альтернатива `x-default` | Нет резервного варианта для пользователей, чей язык не указан | Добавьте `x-default`, указывающий на URL вашей дефолтной локали | | Несогласованные альтернативы в HTML и карте сайта | Противоречивые сигналы сбивают поисковых роботов | Используйте `resolveCanonicalLocale()` в обоих местах | ## Следующие шаги * Узнайте о [middleware](/docs/next/guides/middleware) для маршрутизации URL по локали * См. справку API для [`resolveCanonicalLocale`](/docs/core/class/methods/locales/resolve-canonical-locale) * Настройте [`customMapping`](/docs/cli/reference/config) в файле `gt.config.json`