技術ブログ
2020年10月12日
[JacaScript][PHP][サーバー]
多言語サイトで自動的に言語を判別する4つの方法
弊社は最大60ヶ国の多言語対応を展開しているため、Webでも国ごとの表示切り替えを要求される場合があります。
国ごとのWebサイトの切り分けといってもいくつか方法があるので、備忘録を兼ねて一つずつ確認していきたいと思います。
各国語言語サイトへ振り分ける4つの方法
以下の方法が考えられます。
それでは一つずつ見ていきましょう。
.htaccessで振り分ける
.htaccessファイルはWebサーバーの基本的な動作をディレクトリ単位で制御することができる設定ファイルです。 多くのウェブサーバで使うことができますが、Nginxを利用しているサーバでは利用できない場合があります。
レンタルサーバーでもまれに利用できないように設定されている場合もありますので、詳しくはお使いのサーバーのヘルプなどを参照してみて下さい。
その名の通り、ファイル名なし、拡張子がhtaccessのファイルです。
Windowsではファイル名なしが作成できないためa.htaccessなどのファイルを作って、FTPでアップロード後にリネームしたりします。
さてそんな.htaccessですが、言語振り分けを考えた場合は、IPアドレスによる制御が考えられます。
RewriteEngine on
RewriteCond %{REMOTE_ADDR} ^xxx\.xxx\.xxx\.xxx$
RewriteRule .* https://www.tti-co.com/ [R=301,L]
・・・ちょっと私もそんなに正規表現の書き方に詳しくないので間違いがあるかもしれません。ごめんなさい。
詳しくは専門のサイトなどをご確認いただければと思います。
まず、
RewriteCond %{REMOTE_ADDR}
の行ですが、
^xxx\.xxx\.xxx\.xxx$
は、対象のIPアドレスを正規表現で指定しています。
「^(~で始まる)」「\.(『.』として扱う)」「$(~で終わる)」
続いて
RewriteRule
の行ですが、
.*
は、リダイレクトさせる対象のディレクトリです。
この場合、全てということになります。
後の
https://www.tti-co.com/
は、リダイレクトさせるURLになります。
後ろの
R=301
は、301リダイレクトさせる(ファイルの移動)意味で、今回各国語対応のサイトにリダイレクトさせる想定でしたので301リダイレクトですが、もし違う場合は302(一時的な移動)でも良いかなと思います。
これを、全IPアドレス分設定することになります。
また、IPアドレスで振り分けする場合、実際そのIPを使わないと正しく設定されたかわからないという問題があります。
その国で使われているIPアドレスは
国/地域別IPアドレス割当数一覧
を見るとわかりますが、数が多くて1行でかけるレベルではありません。
なので、.htaccessを使う場合は、このIPだけ通す、とか、このIPだけ除く、とか狭い使い方が現実的かと思います。
PHPで振り分ける
ほぼこれでいけるかなと思いますが、大手企業のセキュリティが厳しいようなサーバーだとPHP禁止のところもありますね。
PHPで振り分けする場合は、ブラウザの言語設定(ロケールコード)を見て、上位に来ている言語のURLに飛ばすという仕組みになります。
まずブラウザの言語設定とはなんぞやというところですが、Chromeでいうと、「環境設定」を開き、「詳細設定」を開いて、「言語」の中の「言語」タブを開くとでてきます。
(GoogleChromeバージョン: 85.0.4183.102の場合)
優先したい言語を上に持ってきます。
(順番は右の点の部分をクリックするとメニューが表示されます)
PHPでここの情報を読み取って、一番上に表示してある言語に飛ばすということになります。
echo $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$_SERVER['HTTP_ACCEPT_LANGUAGE']
で、現在のロケール設定をすべて取得することができます。
上記の言語設定で
ja,en;q=0.9
という結果になりました。
これは、言語を”,”で区切り、q=の値が優先度の割合だとのこと。(1の場合は省略。)
なので、上記の場合は”ja”が、優先度1.0、”en”が優先度0.9という感じになります。
ですので、これらを分解して
$langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$langs_val = array();
foreach ( $langs as $langs_buf ) {
$langs_val[] = substr($langs_buf, 0, 2);
}
のように書くことで、先頭2文字の国別コードを判別することができます。
ただ、簡体語は”zh-CN”、繁体語は”zh-TW”のように地域コードが必要な場合もありますので、その場合は
$langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$langs_val = array();
foreach ( $langs as $langs_buf ) {
$langs_val[] = preg_replace( '/\;.*/', '', $langs_buf );
}
のように記述することで、地域コードまで取得することが可能になります。
あとは、その値から
if($langs_val[0] == "ja"){
header('Location: /ja/', true, 301);
exit;
}else if($langs_val[0] == "en"){
header('Location: /en/', true, 301);
exit;
}
・・・のように、条件にあわせてリダイレクトなどの分岐処理を行ってあげればOKです。
JavaScriptで振り分ける
PHPで振り分けができない場合、JavaScriptという選択になりますが、JavaScriptも「JavaScriptを効かない」ようにする設定ができますので、万能というわけではありません。
一昔前は訪問者の2〜3%くらい効かないように設定しているユーザーもみられましたが、昨今JavaScriptがないと満足に閲覧できないことも少なくなく、あまり神経質になる必要はないレベルかなとは思います。
JavaScriptの場合は、PHPと同じくブラウザの言語設定の値を読み込んで先頭文字列から振り分けをします。
var lang =
window.navigator.languages || window.navigator.language || window.navigator.userLanguage || window.navigator.browserLanguage;
if(lang == 'ja'){ location.href = 'https://www.tti-co.com/'; }
値の取得方法が
window.navigator.languagesとか
window.navigator.languageとか
複数あるのは、ブラウザによって呼び出し方が異なるためです。
linkタグで振り分ける
最後はHTMLを使った方法です。
<head>〜</head>内にrel=”alternate” hreflang=”x”というタグ(アノテーションタグ)を記述することで、検索結果に各言語・地域ごとに合ったページを表示することができます。
ただ、この方法は検索サイトからの振り分けに対して正しい言語に渡す方法になりますので、振り分けしたい条件によっては向かない場合もあるのではないかと思います。
書き方としてはこんな感じ。
<link rel="alternate" href="https://www.tti-co.com/" hreflang="ja">
<link rel="alternate" href="https://www.tti-co.com/en/" hreflang="en">
hreflangタグは多言語に対応しているページ全てに記述します。
抜け間違いなど内容に注意しましょう。
また、使用する言語が同じで表示する地域によって異なるサイトの場合、内容が重複する恐れもあるため、canonicalタグの併用も必要になります。
正しく誘導することでSEOの効果も期待できますので、正しい設定が行われるように注意しましょう。
リダイレクトの注意点
いかがでしょうか。
多言語振り分けといっても、サイトの作りやどこで扱うか、サーバーの環境は・・・といった条件によって使える技術が異なってきます。
ご自身の状況によって最適な方法をご検討下さい。
また、リダイレクトの方法によってはアクセスログの結果が検索結果やリンクからのアクセスではなくダイレクト流入としてカウントされてしまうといった問題や、パラメータなどが全部消されてしまうので、パラメータが必要な場合はその処理を事前に行う必要があります。
適切な方法、適切な処理でのリダイレクト処理をご検討下さい。
この記事を書いた人
おおつき@TTI
Webディレクター、Webコンサルタント、Webコーダー、日曜プログラマー、他色々やってます。
気になったら
まずはご相談を
あなたの悩みのために専門家がチームを組み、課題解決に取り組みます。
まずはお気軽にお問い合わせください。
日本全国どこでも対応します。