# 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`