XM Cloud のサンプルとなっている sxastarter は1言語でサイトを作ることが前提となっているため、多言語でサイトを運用するためには少し調整が必要です。今回はこの部分を2回にわたって紹介をします。
前提条件
今回は、前提条件として言語フォールバックの設定が適用済とします。言語フォールバックを利用しない場合でも、ja-JP および en-US の言語を追加することで、コンポーネントの実装に関しては確認をすることは可能です。
ブラウザの動作を確認する
ブラウザの言語の設定によって、どのように URL が変わるのかを確認していきます。動作確認としては、https://www.sxastarter.localhost/ にアクセスをする形です。
結果としては以下のような形です。
ブラウザのロケール | URL |
---|---|
ja-JP | https://www.sxastarter.localhost/ja-JP |
en-US | https://www.sxastarter.localhost/en-US |
en | https://www.sxastarter.localhost/ |
fr-fr | https://www.sxastarter.localhost/ |
上記のように、 / にアクセスをすると英語のコンテンツを、日本語とアメリカ英語にロケールを設定しているブラウザにはそれぞれの URL が付与される形となります。
このように en が標準言語になっている状況で確認をしましたが、これを ja-JP に変更した場合の動作を確認します。まず、Vercel で展開しているサイトの DEFAULT_LANGUAGE の値を ja-JP に変更をします。
設定変更後、Redeploy を実行してサイトにアクセスをします。結果と指定化のような動作となりました。
- 変更前
- https://sitecoredemo.jp/ 英語のコンテンツを表示
- 日本語は https://sitecoredemo.jp/ja-JP で表示されます
- 変更後
- https://sitecoredemo.jp/ 日本語のコンテンツを表示
- 英語は https://sitecoredemo.jp/en で表示されます
このようにデフォルトの言語の設定を変更することで、言語を表示するための URL が変わることを確認しました。
ロケールを取得する
続いて標準のコンポーネントにおいて、ロケールを取得することは可能でしょうか?まず最初に、Navigation コンポーネント( src\sxastarter\src\components\Navigation.tsx )の Default 関数に対して、以下の一行を追加してみます。
console.log(sitecoreContext);
記載をしたあと、例えば https://www.sxastarter.localhost/en-US にアクセスをすると、以下のような Json データを取得していることが分かります。
{
route: {
name: 'Home',
displayName: 'Home',
fields: {
Content: [Object],
Title: [Object],
NavigationTitle: [Object],
NavigationClass: null,
NavigationFilter: [],
SxaTags: [],
'Page Design': null
},
databaseName: 'master',
deviceId: 'fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3',
itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
itemLanguage: 'en-US',
itemVersion: 1,
layoutId: '96e5f4ba-a2cf-4a4c-a4e7-64da88226362',
templateId: '504f30e9-71ae-42fe-9f81-b5006338d516',
templateName: 'Page',
placeholders: {
'headless-header': [Array],
'headless-main': [Array],
'headless-footer': [Array]
}
},
itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
pageEditing: false,
site: { name: 'sxastarter' },
pageState: 'normal',
editMode: 'chromes',
language: 'en-US',
itemPath: '/',
variantId: '_default'
}
なお、en のロケールもしくはそれ以外の言語でアクセスをした場合は、以下の Json が返ってきます。
{
route: {
name: 'Home',
displayName: 'Home',
fields: {
Content: [Object],
Title: [Object],
NavigationTitle: [Object],
NavigationClass: null,
NavigationFilter: [],
SxaTags: [],
'Page Design': null
},
databaseName: 'master',
deviceId: 'fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3',
itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
itemLanguage: 'en',
itemVersion: 1,
layoutId: '96e5f4ba-a2cf-4a4c-a4e7-64da88226362',
templateId: '504f30e9-71ae-42fe-9f81-b5006338d516',
templateName: 'Page',
placeholders: {
'headless-header': [Array],
'headless-main': [Array],
'headless-footer': [Array]
}
},
itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
pageEditing: false,
site: { name: 'sxastarter' },
pageState: 'normal',
editMode: 'chromes',
language: 'en',
itemPath: '/',
variantId: '_default'
}
動作としては、sitecoreContext.language にコンテンツで設定をしている言語情報が入ってきていることを確認することができました。
URL を調整する
まずは Navigation コンポーネントにおいて、以下のような URL でリンクが生成されるように設定していきます。
- ja-JP および en-US が返ってきたときに、リンクの URL としてそれぞれのロケールを追加する
- en が返ってきたときは、ロケールを追加しない
Navigation コンポーネント( src\sxastarter\src\components\Navigation.tsx )において、リンク情報として、NavigationProps という形で型定義をしています。これに、locale を追加します。
type NavigationProps = {
params?: { [key: string]: string };
fields: Fields;
handleClick: (event?: React.MouseEvent<HTMLElement>) => void;
relativeLevel: number;
locale: string;
};
この locale には sitecoreContext.language が en もしくは undefined の時にはパスを追加せず、ja-JP および en-US の時には URL として追加する形にします。
この部分のための処理は以下のコードを利用しています。
const getLocale = function (props: SitecoreContextValue): string {
let locale;
if (!props.language || props.language === process.env.DEFAULT_LANGUAGE) {
locale = '';
} else {
locale = '/' + props.language;
}
return locale;
};
この関数では英語の場合はルートを、そうではない場合はロケールの URL を返すようにしています。追加をした関数を利用して、default では sitecoreContext を渡して contentLocaleを設定するようにします。
const contentLocale = getLocale(sitecoreContext);
そして NavigationList を呼び出すところで以下のように locale を渡すようにします。
<NavigationList
key={`${key}${element.Id}`}
fields={element}
handleClick={(event: React.MouseEvent<HTMLElement>) => handleToggleMenu(event, false)}
relativeLevel={1}
locale={contentLocale}
/>
NavigationList に関しては自分を再起呼び出しをしていますので、その中では値を引き継ぐ形でコードを記載します。
if (props.fields.Children && props.fields.Children.length) {
children = props.fields.Children.map((element: Fields, index: number) => (
<NavigationList
key={`${index}${element.Id}`}
fields={element}
handleClick={props.handleClick}
relativeLevel={props.relativeLevel + 1}
locale={props.locale}
/>
));
}
これで値として locale の受け渡しは実装しました。あとはこの値を URL として実装する必要があります。URL を生成する際に利用している getLinkField のコードにて locale に関する情報を追加します。
const getLinkField = (props: NavigationProps): LinkField => ({
value: {
href: props.locale + props.fields.Href,
title: getLinkTitle(props),
querystring: props.fields.Querystring,
},
});
これで URL に関しての調整が完了しました。
動作確認
サイトにアクセスをして、URL を確認します。以下の画面が変更後で、URL に正しくロケールが追加されていることを確認することができます。
まとめ
今回は、多言語サイトでどのような URL の設定をしていくのか、表示される URL に関しては調整されるが、コンポーネントで出力する URL をどういう形で調整をするのか、に関して Navigation コンポーネントを利用して紹介しました。
実はこれだけでは Navigation コンポーネントは処理が不足しているため、次回もう一度別の問題を解決したいと思います。