少し前に、Googleの「Webmaster Central blog」でファセットナビゲーションのベストプラクティスとワーストプラクティスに関する記事が投稿されました。Maile Ohye氏とMehmet Aktuna氏によって書かれた「Faceted navigation best (and 5 of the worst) practices」です。
公式訳が公開されそう&とにかく長いため紹介をしようかどうか迷っていたのですが、とても勉強になったので、私なりにまとめて記事にしておきます。ただ、(今でも長いですが)翻訳をそのまま載せるとどうも冗長になってしまう気がしたので、私なりに意訳したり端折ったりしたところがあることを、あらかじめご了承ください。前回の記事同様、公式が出る前のつなぎ程度に参考にしていただければと思います。また、おかしな訳や解釈がありましたら、ご指摘いだけると嬉しいです。
「ファセットナビゲーション(Faceted Navigation)」または「ファセット検索」は、簡単にいうと、ユーザーがサイト内を検索するとき、あらかじめユーザーにとって価値がありそうな絞り込みの条件を用意しておくことで、ユーザーが検索条件を入力することなく選択し絞り込むことのできるナビゲーションのことです(こちらの説明が分かりやすいです)。
今回紹介する記事の冒頭に書かれているように、ファセットナビゲーションは、色や価格帯などで絞り込めるため、訪問者にとっては非常に便利です。しかし、多くはパラメータの組み合わせによって、内容が同じでもURLが異なる重複コンテンツを作ってしまいます。そのため、検索エンジンのクローラーがページの更新に合わせて素早くクロールすることができません。
例えば、ファセット・ナビゲーションが生成するURLは次のようになります。
http://www.example.com/category.php?category=gummy-candies&price=5-10&price=over-10
同記事で紹介されているのは、主にこのURLの設定方法や扱いに関するベストプラクティスです。クローラーにとって(同時に検索ユーザーにとって)意味のあるURLを確実に設定し、逆に不要なURLを取り除いたり、統合したりすることによって減らす方法について解説されています。
背景
理想的な状態は、固有のコンテンツ(個々の商品または記事)あるいはそれらのカテゴリーが、固有のアクセス可能なURLを持つことであり、それぞれのURLに到達することができるクリックパスが用意されていることです。
例えば、カテゴリーページ向けのURLの典型例は次のようなものです。
http://www.example.com/category.php?category=gummy-candies
また、個別アイテムのページの場合は次のようになります。
http://www.example.com/product.php?item=swedish-fish
一方で、ファセットナビゲーションによって生じる可能性がある重複には次のものがあります。
- 同じアイテムページに複数のURLが割り当てられていること。
- 正規ページ:
example.com/product.php?item=swedish-fish
- 重複ページ:
example.com/product.php?item=swedish-fish&category=gummy-candies&price=5-10
- 正規ページ:
- 利用者にとって価値のないカテゴリーURLが多数あること。
example.com/category.php?category=gummy-candies&taste=sour&price=5-10
- ユーザーがあまり検索しないカテゴリーを設置していること。
- 複数のカテゴリーからひとつの同じアイテムに辿りついてもあまり意味がありません。
- 多数のカテゴリーがあることで、どれをインデックスすべきかをクローラーが判断しづらくなること。
- クローラーのキャパシティが、更新・新規ページではなく重複されたページに割り当てられてしまうことによって、処理能力が損なわれてしまうこと。
example.com/category.php?category=gummy-candies&taste=sour&price=over-10
- 0件の場合はレスポンスコード404を返すべきで、検索エンジンにとって価値がないこと。
- ユーザーにとっても価値がないこと。
ファセットナビゲーションのワースト(検索エンジンに扱いにくい)プラクティス
上記を踏まえた上で、同記事では5つのワーストプラクティスを例示しています。
【ワーストプラクティス1】
非標準のURLパラメータのエンコーディング。例えば、キーと値のペアが「イコール(=)とアンパサンド(&)」ではなく、コンマ(,)やブラケット([])になっているなど●ワーストプラクティス
example.com/category?[category:gummy-candy][sort:price-low-to-high][sid:789]
example.com/category?category,gummy-candy,,sort,lowtohigh,,sid,789
●ベストプラクティス
example.com/category?category=gummy-candy&sort=low-to-high&sid=789
【ワーストプラクティス2】
ページの内容を変更しない値を、パラメータではなくディレクトリやファイルパスで利用すること●ワーストプラクティス
「
/c123/
」がカテゴリーで、「/s789/
」がページ内容に影響しないセッションIDの場合。example.com/c123/s789/product?swedish-fish
●グッドプラクティス
ディレクトリ「
/gummy-candy/
」がページの内容を変化させる場合。example.com/gummy-candy/product?item=swedish-fish&sid=789
●ベストプラクティス
効率のよいクロールの仕方を検索エンジンン委ねるフレキシビリティを備えたパラメータ。
example.com/product?item=swedish-fish&category=gummy-candy&sid=789
クローラーにとって、パス上に直接書かれた値が、意味のあるものか意味がないものかを区別するのは困難です。また、クローラーが、与えられた値すべてのバリエーションにアクセスする必要がないなら、URLパラメータの方が、クローラーにテストし決定するフレキシビリティを与えます。
【ワーストプラクティス3】
ユーザーによって生成される値を、URLのパラメータに変えていくこと(可能性としては無限)。それらのURLはクロールもインデックスも可能ですが、検索結果上は不要です●ワーストプラクティス
例えば、クロールやインデックスが可能なURLに、経度/緯度や「~日前」のような値がつくもの。
example.com/find-a-doctor?radius=15&latitude=40.7565068&longitude=-73.9668408
example.com/article?category=health&days-ago=7
●ベストプラクティス
効率のよいクロールの仕方を検索エンジンン委ねるフレキシビリティを備えたパラメータ。
example.com/find-a-doctor?city=san-francisco&neighborhood=soma
example.com/articles?category=health&date=january-10-2014
クローラーにとって価値のないURLを作ってしまう値を利用するより、一般的な値としてカテゴリーページを作り、そこに単なる検索結果以上の価値を与えるような有益な情報を加える方が望ましいです。他方で、ユーザーによって生成される値は別のディレクトリに置き、そのディレクトリ自体を「robots.txt」でブロックすることを検討します。
example.com/filtering/find-a-doctor?radius=15&latitude=40.7565068&longitude=-73.9668408
example.com/filtering/articles?category=health&days-ago=7
「robots.txt」に次のように記述:
User-agent: *
Disallow: /filtering/【ワーストプラクティス4】
ロジックを伴わないURLパラメータを付けること●ワーストプラクティス
example.com/gummy-candy/lollipops/gummy-candy/gummy-candy/product?swedish-fish
example.com/product?cat=gummy-candy&cat=lollipops&cat=gummy-candy&cat=gummy-candy&item=swedish-fish
●ベタープラクティス
example.com/gummy-candy/product?item=swedish-fish
●ベストプラクティス
効率のよいクロールの仕方を検索エンジンン委ねるフレキシビリティを備えたパラメータ。
example.com/product?item=swedish-fish&category=gummy-candy
無関係なパラメータは、クロールやインデクシングに非効率で、重複を増やすだけです。そのため、URL生成の前に不要なパラメータを取り除いて「ハウスキーピング」を実行します。もしユーザーセッションに多くのパラメータが必要ならパラメータを付与するより、cookieで情報を隠す方が好ましいです。
【ワーストプラクティス5】
0件の結果にさらなる絞り込み(フィルタリング)を提供すること●ワーストプラクティス
結果が0件の場合でも、ユーザーが絞り込み機能を利用できる場合。
●ベストプラクティス
(アイテムが存在する)妥当な選択にだけリンクを生成します。0件の場合は、絞り込みのオプションをグレーアウトします。さらに、ユーザービリティの向上のために、フィルタの横にアイテム数を付け加えることを検討します。
アイテムが存在するときだけURLを生成することで、無価値なURLを減らし、クロールスペース(Googlebotに確認されたサイト上のURLの総数)を最小限に抑えます。もし一時的な品切れで、他に有益なコンテンツを含んでいないページがあれば、ステータスコード404を返します。404を返すことで、関連商品を見つけるためのナビゲーションや検索ボックスを付けてユーザーを助けることができるようになります。
新しいファセットナビゲーションの実装あるいは再設計のためのベストプラクティス
- 個々のアイテムに辿りつくのために、少なくともひとつはクリックパスを用意する必要があります。その時に必要なパラメータを決定します。例えば「
item-id
」、「category-id
」、「page
」等がそれに当たります。 - 必要なパラメータと不要なパラメータを選択します。ここで例としてあげられているのは、「
example.com/category.php?category=gummy-candies&taste=sour&price=over-10
」です。この中で「price
」は重複を生むだけの不要なパラメータです。
他にも例としては次のようになります。- 価値のあるパラメータ: 「
item-id
」「category-id
」「name
」「brand
」等 - 不要なパラメータ: 「
session-id
」「price-range
」等
- 価値のあるパラメータ: 「
- 不要なパラメータを含むURLは次のように対処します。
オプション1: 「rel=”nofollow”」付きリンク
「robots.txt」と異なり、不要なURLがクロールされることを防ぐことはできないが、クローラーが不要なURLを探索するのを最小限にとどめ、クロールスペースの広がりを抑制できます。また、「rel=”canonical”」を使うことで、不要なURLからのインデクシングシグナルを統合することができます。(例えば「
example.com/category.php?category=gummy-candies&taste=sour&price=5-10
」を全件表示ページである「example.com/category.php?category=gummy-candies&taste=sour&page=all
」に正規化できます。)オプション2: 「robots.txt」の「disallow」
例えば「
/filtering/
」などのディレクトリを設けて、クローラーをブロックします。そうすることで、価値のあるURLだけをクロールさせることができるようになります。example.com/filtering/category.php?category=gummy-candies&price=5-10
そして、「robots.txt」で「disallow」にします。
User-agent: *
Disallow: /filtering/オプション3: 別ホスト
CDNを使っていないなら(CDNを利用している場合、以下のウェブマスターツールを使うのが難しい)、別のホストに不要なパラメータを持つURLを移すことを検討できます。例えば、メインホストを「www.example.com」で作成し、別のホストを「www2.example.com」とします。その上で、ウェブマスターツールでメインホストへのクロール速度を高く設定し、別のホストの方は低くしておきます。この時次の2つに注意しましょう。
- メインホスト上で、アイテム全てに対し、クリックパスが少なくともひとつは残っていることを確認しましょう。
- インデクシングシグナルを統一したい場合、2つ目のホストにメインホスト上のURLに向けた「rel=”canonical”」を設置します。
- アイテムが存在しない場合、そのカテゴリーやフィルタをクリックできないようにします。
- URLパラメータのロジックを決めておきます。
- 不要なパラメータは取り除きます。
×example.com/product?cat=gummy-candy&cat=lollipops&cat=gummy-candy&item=swedish-fish
- 価値のあるパラメータを先に、不要なパラメータを最後に持ってくるなど、一貫性のある順序を維持します。
×example.com/category.php?session-id=123&tracking-id=456&category=gummy-candies&taste=sour
- 不要なパラメータは取り除きます。
- 「rel=”canonical”」を利用します。
- 次の方法でページネートされたコンテンツのインデクシングを改善します。
- 繋がりのある個々のページ(「
category=gummy-candies&page=1
」、「category=gummy-candies&page=2
」など)を「rel=”canonical”」を使って、前件表示のページに向けます。 - ページネーションのマークアップ「rel=”next”」と「rel=”prev”」を利用します。
- 繋がりのある個々のページ(「
- URLを更新せずに、コンテンツを動的にソートしたり、フィルタリングしたり、隠したりするためにJavaScriptを使う場合は、そうしてもサイト上に、クロールやインデックスが可能なメインカテゴリのページや個々のアイテムのページが残っているようにしておきます。例えば、ホームページ(つまりひとつのURL)だけで全てのコンテンツを動的に変化させて、表示させるようなことは避けるべきです。ページに辿りつくためのURLがひとつしかなくなってしまいます。
- サイトマップには正規のURLだけを含めます。
既にファセットナビゲーションを持っているサイトのためのベストプラクティス
- (可能なら)標準的なエンコーディングとキーと値のペアを使います。
- セッションIDのようなコンテンツを変化させない値が標準的なキーと値のペアの値で実装されていることを確認します。
- アイテムが存在しない時はクリックできず、URLも生成されないようにしておく
- URLパラメータのロジックを決めておきます。
- 不要なパラメータは取り除きます。
×example.com/product?cat=gummy-candy&cat=lollipops&cat=gummy-candy&item=swedish-fish
- 価値のあるパラメータを先に、不要なパラメータを最後に持ってくるなど、一貫性のある順序を維持します。
×example.com/category.php?session-id=123&tracking-id=456&category=gummy-candies&taste=sour
- 不要なパラメータは取り除きます。
- URLパラメータの挙動に関してしっかりとした理解があるならば、ウェブマスターツールの「URLパラメータ」を利用します。パラメータ毎の効果をGoogleに伝えたり、クロールする/しないを細かく設定したりすることができます。
- URLを更新せずに、コンテンツを動的にソートしたり、フィルタリングしたり、隠したりするためにJavaScriptを使う場合は、そうしてもサイト上に、クロールやインデックスが可能なメインカテゴリのページや個々のアイテムのページが残っているようにしておきます。例えば、ホームページ(つまりひとつのURL)だけで全てのコンテンツを動的に変化させて、表示させるようなことは避けるべきです。ページに辿りつくためのURLがひとつしかなくなってしまいます。
- 「rel=”canonical”」を利用します。
- 次の方法でページネートされたコンテンツのインデクシングを改善します。
- 繋がりのある個々のページ(「
category=gummy-candies&page=1
」、「category=gummy-candies&page=2
」など)を「rel=”canonical”」を使って、前件表示のページに向けます。 - ページネーションのマークアップ「rel=”next”」と「rel=”prev”」を利用します。
- 繋がりのある個々のページ(「
- サイトマップには正規のURLだけを含めます。