多言語サイトを外国人ユーザーの検索結果に反映させる方法

2018年2月13日

同一コンテンツを多言語で公開するサイトを、ユーザーの言語環境に応じて検索結果に表示させる方法を解説します。

基本言語が「日本語」に設定されているブラウザを使っている人が検索すると日本語用のサイトが表示され、基本言語が「英語」に設定されているブラウザを使っている人が検索すると英語用のサイトが表示される、といった具合です。

<head>タグ内に設定を追加する

全てのウェブページは直接または間接的に生成されたHTMLによって表され、ブラウザはHTMLを読み取って画面に表示します。HTMLの冒頭には<head>と</head>で囲まれた「ヘッドブロック」があり、そのページに関する補足的な情報を記述しておけば、ブラウザや検索エンジンがそれぞれに意味を解釈して、適切な扱いをしてくれます。

たとえば、とあるサイトのトップページが「http://www.sample.jp/」だとしましょう。
トップページの<head>タグ内に以下の記述を追加します。

<link rel="alternate" hreflang="ja" href="http://www.sample.jp/">
<link rel="alternate" hreflang="en" href="http://www.sample.jp/en/">

すると、次の意味を表します。

・このページは「http://www.sample.jp/」という日本語ページの代替コンテンツである。
・このページは「http://www.sample.jp/en/」という英語ページの代替コンテンツである。

検索エンジン(ここではGoogleを指します)は、この設定を読み取ります。そして、検索ユーザーがブラウザで検索を行ったとき、ブラウザから送られてくる言語設定の情報と照らし合わせて

「日本語のブラウザには日本語のページを検索結果に表示させる」
「英語のブラウザには英語のページを検索結果に表示させる」

といった振り分けが行えるようになります。

ただし、<head>タグ内に記述する設定に絶対的な強制力があるとは限りません。検索エンジンが設定をどのように扱うかは検索エンジンのアルゴリズムが決めることであって、私たちユーザーがどうこうできることではありません。

PHPを使えば全てのページに一括でタグを記述できる

この設定はサイト全体で共通なのではなく、ページごとに個別に行わなければなりません。なぜなら、href属性には「そのページの代替コンテンツがどのURLなのか」を指定しなければならないからです。

たとえば、とあるサイトのお問い合わせページが「http://www.sample.jp/contact/」の場合、お問い合わせページの<head>タグ内には次の記述を入れなければなりません。

<link rel="alternate" hreflang="ja" href="http://www.sample.jp/contact/">
<link rel="alternate" hreflang="en" href="http://www.sample.jp/en/contact/">

ページ数の多いサイトだと1ページずつこのような記述を入れるのは大変ですが、PHPのような、サーバー側で動的にHTMLを生成できるプログラム言語を使ったサイトなら、ページごとに記述しなくても済みます。(WordPressはPHPなので以下の方法が使えます)。

たとえば日本語サイトには

//プロトコル名(通信規約名)を取得。http:// や https:// の部分。
$prot = empty($_SERVER["HTTPS"]) ? "http://" : "https://";
//ホスト名を取得。www.sample.jp の部分。
$host = $_SERVER["HTTP_HOST"];
//要求されたページのURLを取得。「/contact/」や「/faq/」など個別の部分。
$uri = $_SERVER["REQUEST_URI"];
//<link>タグを挿入。
echo '<link rel="alternate" hreflang="ja" href="' . $prot . $host . $uri . '">';
echo '<link rel="alternate" hreflang="en" href="' . $prot . $host . 'en/' . $uri . '">';

と記述しておくと、

トップページには

<link rel="alternate" hreflang="ja" href="http://www.sample.jp/">
<link rel="alternate" hreflang="en" href="http://www.sample.jp/en/">

お問い合わせページには

<link rel="alternate" hreflang="ja" href="http://www.sample.jp/contact/">
<link rel="alternate" hreflang="en" href="http://www.sample.jp/en/contact/">

というように、自動的にページごとのタグが挿入されます。

同じように考えて、英語サイト側は次のようにします。

//プロトコル名(通信規約名)を取得。http:// や https:// の部分。
$prot = empty($_SERVER["HTTPS"]) ? "http://" : "https://";
//ホスト名を取得。www.sample.jp の部分。
$host = $_SERVER["HTTP_HOST"];
//要求されたページのURLを取得。「/contact/」や「/faq/」など個別の部分。
$uri = $_SERVER["REQUEST_URI"];
//<link>タグを挿入。
echo '<link rel="alternate" hreflang="en" href="' . $prot . $host . $uri . '">';
echo '<link rel="alternate" hreflang="ja" href="' . $prot . $host . str_replace("en/", "/", $uri) . '">';

【8行目】
$hostにはホスト名が入ります。本例のように、英語サイトに日本語サイトと同じドメインのサブディレクトリを割り当てている場合、$hostには日本語サイトと同じホスト名が入ります。(例:www.sample.jp)
$uriはホスト名より後ろの部分が入ります。(例:en/)
合わせると、href=”http://www.sample.jp/en/” が得られます。

【9行目】
こちらは少し工夫がいります。欲しい結果は href=”http://www.sample.jp/ なのですが、$uriには en/ が入ってくるので、日本語サイトのURLにするためには en/ を取り除かなくてはなりません。そこで、PHPの文字列置換関数 str_replace を使います。

str_replace関数:PHP公式マニュアル

こうすると、href=”http://www.sample.jp/” が得られます。

WordPressならここに書こう

WordPressの多くのテーマ(テンプレート)は、header.php あるいは header.php の中から間接的に読み込んでいる別の名前のテンプレート(例:head.php)のどこかに、<head>~</head> で囲まれた部分が記述されているので、その範囲内に記述すればよいのですが、初心者の方は次の基本事項を無視してテンプレートを壊してしまいがちなので気をつけてください。

WordPressのテンプレートは、ファイルの末尾の拡張子が「.php」となっていますが、サーバーはこの種類のファイルをHTMLとしてではなくPHPの文法で記述されたプログラムソースだとみなします。

そのため、HTMLの中にプログラムを混在させることができるPHPにおいては、「ここからここまでの範囲はHTMLで書いてあります」「ここからここまでの範囲はPHPで書いてあります」というように、どちらで記述しているのかという境界線を正確に示さなければなりません。ここを間違えてしまうと、HTMLで書いた部分をPHPのプログラムとして実行しようとしてしまい、文法違反のエラーが発生してしまい、サイトが表示されなくなります。

PHPでは、<?php?>で囲まれた部分はPHPのプログラムだとみなされます。そのため、この範囲ではHTMLのタグや普通のテキストを“そのまま”入れることは許されません。入れたい場合は、HTMLに変換する echo 命令などを組み合わせなければなりません。

2つほど例を挙げます。

<?php
//▼ここから下はPHPの世界。

<p>このように記述すると文法違反でエラーになります。</p>
echo '<p>こうするとHTMLに変換してくれます。</p>';

//▲ここから上はPHPの世界。
?>

<!--▼ここから下はHTMLの世界。-->
<p>ここではHTMLのタグがそのまま使えます。</p>
普通のテキストも使えます。
<!--▲ここから上はHTMLの世界。-->

PHPの範囲が複数行にまたがる場合は、上記のように<?php?>の間を改行するとみやすくなります。

<?php
$next_year = 2020;
?>
<p>次のオリンピックは<?php echo $next_year; ?>年です。</p>

PHPの範囲が短い場合は、上記のように<?php?>の間を改行しないで1行に記述してもかまいません。

これは、WordPressのテンプレートを直接書き換えるカスタマイズを行う場合に絶対に押さえておかないといけない基礎知識なので、安易にネットで見つけたコードをコピペせずに、きちんと理解してから使うようにしましょう。

本題のコードを書き直すと次のようになります。

<!DOCTYPE html>
<html>
<head>
<meta charset="<?php bloginfo('charset'); ?>" />
<?php
//プロトコル名(通信規約名)を取得。http:// や https:// の部分。
$prot = empty($_SERVER["HTTPS"]) ? "http://" : "https://";
//ホスト名を取得。www.sample.jp の部分。
$host = $_SERVER["HTTP_HOST"];
//要求されたページのURLを取得。「/contact/」や「/faq/」など個別の部分。
$uri  = $_SERVER["REQUEST_URI"];
//<link>タグを挿入。
echo '<link rel="alternate" hreflang="ja" href="' . $prot . $host . $uri . '">';
echo '<link rel="alternate" hreflang="en" href="' . $prot . $host . 'en/' . $uri . '">';
?>
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
・・・

追加した部分は5行目から15行目までです。必ずご自身のWordPressテーマのテンプレートとの対応関係を紐解いてからお使いください。