# General Translation React SDKs (gt-react, gt-next, gt-react-native): 管理区域设置别名的 SEO
URL: https://generaltranslation.com/zh/docs/react/nextjs/locale-alias-seo.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 如何在 Next.js URL 中使用自定义区域设置别名，同时为搜索引擎发布规范语言元数据。

区域设置别名允许路由使用 `/cn` 之类的自定义路径片段，而翻译则使用规范的 BCP 47 代码 `zh`。`gt-next` 会为翻译和路由解析映射关系，但你的应用仍需负责 `<html lang>`、规范 URL、语言替代项和站点地图条目。

## 配置别名 [#configure]

使用 [`customMapping`](/docs/react/reference/config#custom-mapping) 将 URL 中的区域设置映射为其规范代码：

```json title="gt.config.json"
{
  "defaultLocale": "en-US",
  "locales": ["en-US", "cn", "ja"],
  "customMapping": {
    "cn": {
      "code": "zh",
      "name": "Mandarin"
    }
  }
}
```

middleware 会将 `/cn` 识别为本地化路由。当需要使用规范区域设置时，General Translation 会将 `cn` 解析为 `zh`。

请在 SEO 代码中区分使用这两个值：

* 在路由 URL 中使用**别名**，例如 `/cn/about`。
* 在 `lang` 和 `hreflang` 中使用**规范 BCP 47 代码**，例如 `zh`。

## 设置文档语言 [#document-language]

设置 `<html lang>` 属性前，先解析路由的区域设置：

```tsx title="app/[locale]/layout.tsx"
import { resolveCanonicalLocale } from 'gt-next/server';

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;
  const canonicalLocale = resolveCanonicalLocale(locale);

  return (
    <html lang={canonicalLocale}>
      <body>{children}</body>
    </html>
  );
}
```

如果不进行此转换，`/cn` 路由会渲染为 `lang="cn"`，而这不是有效的中文语言标签。

## 发布页面替代项 [#page-alternates]

Next.js 会根据 `metadata.alternates.languages` 生成 `hreflang` 链接。使用规范代码作为对象键，以基于别名的路由作为值：

此首页示例应添加到本地化页面中。请在每个嵌套页面的元数据中构建特定路由的 URL。

```tsx title="app/[locale]/page.tsx"
import type { Metadata } from 'next';
import { resolveCanonicalLocale } from 'gt-next/server';

const locales = ['en-US', 'cn', 'ja'];
const baseUrl = 'https://example.com';

export async function generateMetadata({
  params,
}: {
  params: Promise<{ locale: string }>;
}): Promise<Metadata> {
  const { locale } = await params;
  const languages = Object.fromEntries(
    locales.map((urlLocale) => [
      resolveCanonicalLocale(urlLocale),
      `${baseUrl}/${urlLocale}`,
    ])
  );

  return {
    alternates: {
      canonical: `${baseUrl}/${locale}`,
      languages: {
        ...languages,
        'x-default': `${baseUrl}/en-US`,
      },
    },
  };
}
```

这会生成一个语言为 `zh`、URL 仍为 `/cn` 的替代版本。每个规范语言键只能添加一个 URL；否则，后添加的条目会覆盖先前的条目。

如果 `/cn` 和 `/zh` 都能渲染同一页面，请选择一个首选 URL，并将两个页面的 `canonical` 值都指向该 URL。这样可避免为相同的本地化内容发布重复且可被索引的 URL。

## 添加站点地图替代项 [#sitemap]

在 `app/sitemap.ts` 中使用相同的映射：

```ts title="app/sitemap.ts"
import type { MetadataRoute } from 'next';
import { resolveCanonicalLocale } from 'gt-next/server';

const locales = ['en-US', 'cn', 'ja'];
const pages = ['', '/about', '/pricing'];
const baseUrl = 'https://example.com';

export default function sitemap(): MetadataRoute.Sitemap {
  return pages.map((page) => ({
    url: `${baseUrl}/en-US${page}`,
    alternates: {
      languages: {
        ...Object.fromEntries(
          locales.map((urlLocale) => [
            resolveCanonicalLocale(urlLocale),
            `${baseUrl}/${urlLocale}${page}`,
          ])
        ),
        'x-default': `${baseUrl}/en-US${page}`,
      },
    },
  }));
}
```

确保页面元数据和站点地图中的语言到 URL 映射一致。仅在对应的本地化页面存在时添加备用链接。

## Next steps

- /docs/react/nextjs/app-router-middleware
- /docs/react/nextjs/app-router-static-site-generation
- /docs/react/nextjs/registering-request-locales
- /docs/react/nextjs/cache-components

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
