# gt-next: General Translation Next.js SDK: ロケールエイリアスとSEO URL: https://generaltranslation.com/ja/docs/next/guides/locale-aliases.mdx --- title: ロケールエイリアスとSEO description: 検索エンジン向けの BCP 47 準拠を維持しつつ、URLルーティングにカスタムのロケールエイリアスを使用します --- ロケールエイリアスを使うと、URL でカスタムのロケールコード (例: `/zh/` の代わりに `/cn/`) を使用しながら、検索エンジンが求める [BCP 47 標準](https://www.w3.org/International/articles/language-tags/) に準拠した SEO メタデータを維持できます。 ## なぜエイリアスが必要なのか? `zh` (中国語) や `zh-Hant` (繁体字中国語) のような BCP 47 ロケールコードは、Web上で言語を識別するための標準です。 ただし、ブランディング、わかりやすさ、または地域上の理由から、URL パスでは別のコードを使いたいことがあります。たとえば、中国語圏の利用者向けに `/zh/` ではなく `/cn/` を使うケースです。 GT では、`gt.config.json` の **カスタムマッピング** によってこれをサポートしています。エイリアスはルーティングと URL パスに使用され、正規の BCP 47 コードは検索エンジンが参照する箇所で使用されます。 **SEO 要件:** 検索エンジンが認識するのは [BCP 47 ロケールコード](https://www.w3.org/International/articles/language-tags/) のみです。 `hreflang` 属性や `` に `cn` のような標準外コードを使うと、検索エンジンはロケール指定を無視します。 ## セットアップ ### ステップ1: カスタムマッピングを設定する 各エイリアスごとに、`gt.config.json` に `customMapping` 項目を追加します: ```json title="gt.config.json" { "defaultLocale": "en-US", "locales": ["en-US", "cn", "ja", "zh-Hant"], "customMapping": { "cn": { "code": "zh", "name": "Mandarin" } } } ``` ここで、`cn` は URL とミドルウェアルーティングで使うエイリアスで、`zh` は正規の BCP 47 コードです。 ### ステップ 2: middleware を通常どおり使用する [middleware](/docs/next/guides/middleware) と `[locale]` ダイナミックルートは、エイリアスコードでもそのまま動作します。`/cn/about` にアクセスしたユーザーには中国語のコンテンツが配信されるため、ルーティング用の特別な処理は不要です。 ## SEO における BCP 47 準拠 エイリアスはルーティングでは問題なく機能しますが、次の 3 か所では、エイリアスではなく正規の BCP 47 コードを**必ず**使用する必要があります。 1. `` タグの `lang` 属性 2. ページのメタデータ内の代替リンクタグ 3. サイトマップ内の代替エントリ GT には、エイリアスを対応する BCP 47 コードに変換する `resolveCanonicalLocale()` メソッドがあります。これは `gt-next/server` の `getGTClass` 経由で利用できます。 ```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']; // 正規のBCP 47コードをキーとしてalternatesを構築する 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` の値には正規コード (`cn` ではなく `zh`) が使われますが、`href` の URL では引き続きエイリアスのパス (`/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) => { // 正規コードで言語の代替URLを構築する 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, }, }; }); } ``` これにより、適切な`hreflang`属性を持つサイトマップXMLが生成されます。 ```xml https://example.com ``` ## よくある間違い | 間違い | 影響 | 修正方法 | | ----------------------------- | ---------------------- | ------------------------------------------------- | | `` でエイリアスコードを使う | 検索エンジンがページの言語を判別できない | `lang` 属性には `resolveCanonicalLocale()` を使用します | | `hreflang` でエイリアスコードを使う | 検索エンジンに代替リンクが無視される | `hreflang` の値には `resolveCanonicalLocale()` を使用します | | `x-default` の代替リンクがない | 一覧にない言語のユーザー向けの案内先がない | デフォルトロケールの URL を指す `x-default` を追加します | | HTML とサイトマップで代替リンクの内容が一致していない | 矛盾したシグナルによってクローラーが混乱する | 両方で `resolveCanonicalLocale()` を使用します | ## 次のステップ * ロケールに基づく URL ルーティングについては [middleware](/docs/next/guides/middleware) を参照してください * [`resolveCanonicalLocale`](/docs/core/class/methods/locales/resolve-canonical-locale) の API リファレンスを参照してください * `gt.config.json` で [`customMapping`](/docs/cli/reference/config) を設定してください