検索結果のサイトリンクが変な文言になるとき|全ページ同じtitleを疑う判定と直し方
検索結果のサイトリンクが変な文言になるとき|全ページ同じtitleを疑う判定と直し方
自社名でGoogle検索したときに、サイト名の下に小さなリンクが数本並ぶことがあります。これが「サイトリンク」です。ここに本来はメニュー名(サービス案内・料金・会社概要など)が出てほしいのに、「まずは」「ご連絡ください。」のような本文の途中で切れた文字列が並んでいる、という相談を受けることがあります。
先に結論を書きます。サイトリンクの中身はGoogleが自動生成するもので、直接は指定できません。おかしな文言が出ているときにまず疑うのは、サイト内の全ページで <title> と <meta name="description"> が同一になっていないか、です。
Googleはページを区別するとき、最初に <title> を見ます。全ページのtitleが同じだと、Googleはそのページが何のページか判断できず、代わりに本文中の見出しや文字列を拾ってサイトリンクの表示に使います。「まずは」「ご連絡ください。」が出るのは、Googleがおかしくなったからではなく、区別できる材料をこちらが渡していないからです。
弊社graciautoは名古屋でホームページ制作とLINE公式アカウント構築を手掛けており、SPA(1つのHTMLで全ページを表示する作り)や多店舗展開のサイトを複数運用しています。この記事では、実際にこの症状を直したときの判定手順と実装内容を、そのまま使える形で書きます。
—
前提:サイトリンクは「指定」ではなく「認識させる」もの
作業に入る前に、依頼する側・される側の双方で握っておくべき前提が3つあります。ここがズレたまま進むと、直したのに「思った通りにならなかった」という評価になります。
| 前提 | 内容 |
|---|---|
| 表示内容は自動生成 | どのページをサイトリンクに出すか、どんな文言にするかはGoogle側が決める。HTMLで指名する手段はない |
| 降格機能は廃止済み | かつてSearch Consoleにあった「サイトリンクの降格」(出したくないページを指定する機能)は現在は存在しない |
| 反映は即時ではない | 修正が検索結果に出るまで数日〜数週間かかる。再クロールとインデックス再構築を待つ必要がある |
つまりこちらができるのは「正しく認識させる」ことだけです。ページごとに違うtitleとdescriptionを与え、どのページが何なのかを機械が読める形で明示する。やることはそれに尽きます。
なお、Search Consoleの「URL検査」からインデックス登録をリクエストしておくと再クロールが多少早まります。修正直後にやっておくと待ち時間の短縮になります。
—
30秒でできる判定:全ページのtitleを並べる
原因の切り分けは、想像ではなく実測でやります。手順は1つだけです。主要ページを1本ずつ取得して、titleとdescriptionを並べる。
for p in / /service/ /price/ /about/ /contact/; do
echo "--- $p"
curl -s "https://example.com$p" | grep -o '<title>[^<]*</title>'
done
出力された <title> が全部同じなら、それが原因です。descriptionも同じ要領で確認します。
ブラウザの表示だけ見ていても気づけない
この確認をブラウザで代替できない理由があります。SPAの場合、ページを移動しても実際に配信されているHTMLは同じファイルです。ブラウザのタブに表示されるタイトルがJavaScriptで書き換わっていれば、人間の目には「ページごとに違う」ように見えます。
しかしGoogleが最初に受け取るのは書き換わる前のHTMLです。人が見ている画面と、クローラが受け取るHTMLが食い違う。これがこの症状を見落とす最大の理由です。だから確認は必ずブラウザではなく curl で行います。
あわせて見ておく2項目
| 確認項目 | 正常な状態 |
|---|---|
| canonical | 各ページが自分自身のURLを指している |
| 存在しないURL | /aaa-does-not-exist のような適当なURLが404を返す |
canonicalが全ページ「トップ」を指していると、サブページが「私はトップの複製です」と自己申告している状態になります。titleの重複よりも影響が大きいことがあるため、同時に確認してください。
存在しないURLが200を返す作りも危険です。SPAは「該当ページがなければトップを表示する」構造になっていることがあり、この場合は存在しないURLが無限に生成されるのと同じ扱いになります。
—
実例1:7ページすべてが同じtitleだったSPA型サイト
福岡の生活支援サービス会社のサイトで、実際にこの症状が出ていました。
検索結果のサイトリンクに並んでいたのは「まずは」「ご連絡ください。」「相談風景」といった文言です。いずれも本文中の見出しの断片でした。説明文にいたっては、5つのサイトリンクすべてで同じ文章が使い回されていました。
curl で7ページを取得して並べたところ、7ページすべてで <title> と <meta name="description"> が完全に一致していました。React製のSPAをWordPressのテーマとして組み込んだ構成で、どのURLでも同じHTMLファイルが返る作りだったためです。
直し方:サーバー側で出し分ける
修正は、テーマのPHP側でURLごとにメタ情報を差し替える方式にしました。
- リクエストされたパス(
/service/priceなど)をキーにして、ページ別のtitle・descriptionを持つ配列を用意する - 配信するHTMLの
<title>と<meta name="description">を、そのページの値へ置換する </head>の直前に og:title / og:description / og:url / og:image / twitter:card を追加する
JavaScriptでのDOM書き換えではなく、サーバー側で出し分けるのが正解です。 クローラが最初に受け取るHTMLの時点で正しい値が入るためで、ここを間違えると「直したのに変わらない」という状態が続きます。
実装で見落としやすい点として、パスの正規化があります。/about と /about/(末尾スラッシュの有無)はどちらも到達できることが多いため、比較前に正規化して両方に同じメタが当たるようにしておきます。
titleの中身は「グローバルメニューの名前」を先頭に
titleの文言は凝る必要がありません。サイトのグローバルメニューに書いてある名前をそのまま先頭に置き、末尾にサイト名を付けるのが最も素直です。
生活支援サービス | ○○○○
会社概要 | ○○○○
サイトリンクに出したいのはメニュー名なのですから、Googleに渡す名前もメニュー名に揃えるのが筋が通っています。この案件でも、修正後は7ページすべてが固有のtitleとog:titleを持つ状態になりました。
—
実例2:25店舗で同じ症状が出ていた多店舗サイト
名古屋の美容サロンFCでは、25店舗のサイトが同一構造のSPAで作られており、全店で同じ問題が起きていました。実測で見つかった状態は次の通りです。
| 症状 | 実測内容 |
|---|---|
| title / descriptionが全ページ同一 | 店舗内のどのページも同じ文言 |
| canonicalがトップ固定 | メニューページも口コミページも canonical=/ |
| 存在しないURLが200 | 適当なURLがトップと同じHTMLを返す |
| 旧URLに転送がない | リニューアルで変わった旧URLが転送されず200を返す |
| 本文が空 | クローラが受け取るHTMLの中身が実質ゼロ文字 |
対処は、ページ別のtitle・description・canonicalの出し分け、未知URLの404化、旧URLからの転送、そして本文をHTMLに焼き込む静的化です。修正後は、メニューページのtitleが25店舗すべてでユニークであることを確認しました。
この規模で共通して言えるのは、同じテンプレートから作られたサイトは、1サイトで見つかった不具合が必ず全サイトに存在するということです。1店舗で見つけたら、残りも同じだと考えて棚卸しするほうが早く終わります。
表示していない情報をdescriptionに出さない
多店舗で気をつけたいのが、メタ情報を自動生成するときの中身です。この案件では、料金を意図的に非表示にしている店舗のdescriptionに、テンプレートの既定値として料金が入ってしまう構造になっていました。
検索結果に出た金額を見てから来店した人に、店頭で「料金は店頭でご案内しています」と言うことになれば、期待とのズレがそのままクレームになります。ページに載せていない情報は、descriptionにも構造化データにも出さない。生成ルールの側にこの分岐を持たせておくのが安全です。titleも「料金・メニュー」ではなく「施術メニュー」のように、実際の内容に合わせて変えておきます。
—
あわせて潰しておく「重複ページ」
titleを直すのと同じタイミングで見ておきたいのが、トップと同じ内容を返す余計なページです。
WordPressは初期状態で /sample-page/ というページを持っています。これが消されずに残っていて、しかもトップと同じ内容を200で返し、サイトマップにも載っている——という状態は珍しくありません。Googleから見れば、同じ内容のページが2つある状態です。
対処は次のいずれかです。
- 管理画面から該当ページを削除する(確実)
- 定義していないパスには
noindex,followを返すようにする(テーマ側で一括対応できる)
前者は管理画面での操作が必要なので、実装側で先に後者を入れ、削除は運用側の作業として残す、という進め方が現実的です。
—
直した後に必ずやる検証
ここが最後の関門です。メタ情報の修正は、その後の更新作業で静かに巻き戻ることがあります。
理由は、ページ別のメタやHTMLへの本文焼き込みが「サイトを更新する手順の外側」で作られた資産だからです。通常のデプロイ手順がファイル一式を上書きする作りになっていると、更新のたびに修正前の状態へ戻ります。
厄介なのは、この巻き戻りが目視でもHTTPステータスの確認でも検知できないことです。サイトは正常に表示され、ページも200を返し、利用者には何の異常もありません。壊れているのはクローラが受け取るHTMLだけです。
検知方法は1つ
公開後に本番の <title> を実測する。 これだけです。
curl -s https://example.com/ | grep -o '<title>[^<]*</title>'
期待する文言が返ればOK、素の共通titleが返っていれば巻き戻っています。補助的に、HTMLファイルのサイズ(本文を焼き込んだHTMLは数十KB以上になる)でも判別できます。
この確認は人の記憶に頼らず、主要ページのtitleを一括で取得して異常があれば止まるスクリプトにしておくのが確実です。サイトを触ったら最後に必ず叩く、という運用にすれば、巻き戻りは公開当日に気づけます。
—
よくある質問
Q. サイトリンクに出したいページを指定できませんか?
できません。Googleの自動生成であり、指定用のタグもSearch Consoleの機能もありません。できるのは各ページを正しく認識させることだけです。
Q. 直したのに検索結果が変わりません。
反映には数日〜数週間かかります。まず curl で配信HTMLが正しく変わっているかを確認してください。HTMLが正しければ、あとは再クロール待ちです。Search ConsoleのURL検査からインデックス登録をリクエストしておくと多少早まります。
Q. プラグインでtitleを設定していますが、なぜ全部同じなのですか?
SPAのように1つのHTMLで全ページを表示する構成では、プラグインの設定が反映される「ページ」がそもそも1枚しかない、という状態が起こります。curl で実測すれば、設定と配信内容が食い違っているかどうかがすぐ分かります。
Q. 小規模なサイトでもやる意味はありますか?
あります。ページ数が少ないほど、1ページあたりが検索結果に占める重みは大きくなります。またtitleの重複は、サイトリンクだけでなく通常の検索順位にも影響します。
—
まとめ
- サイトリンクの中身は指定できない。できるのは正しく認識させることだけ
- 変な文言が出ているときは、まず全ページのtitle・descriptionが同一でないかを
curlで実測する - ブラウザ表示では気づけない。クローラが受け取るHTMLを見る
- 修正はサーバー側で出し分ける。JavaScriptでの書き換えでは確実性がない
- titleはグローバルメニューの名前を先頭に置くのが素直
- canonicalのトップ固定・存在しないURLの200・重複ページも同時に潰す
- ページに載せていない情報をdescriptionに出さない
- 直した後はtitleの実測を運用に組み込む。巻き戻りはそれでしか気づけない
- 反映は数日〜数週間。この前提を最初に共有しておく
検索結果の見え方は、サイトの中身を変えなくても改善できる部分が残っていることが多い領域です。まずは自社サイトの主要ページのtitleを並べて見比べるところから始めてみてください。それだけで原因が判明するケースは、想像よりずっと多くあります。