お久しぶりです。フロントエンドエンジニアの右寺です。
Goodpatchのフロントエンド定例会議での話題をみなさんにお届けするCodepatchの第6弾!

今回はあるメンバーからの「サイト内のコンテンツをJSONで管理したいが、SEO的なデメリットをどうにか解決できないか?」という相談に対して出てきたアイデアをみなさんにも共有したいと思います。

SEO的なデメリットとは?

みなさんもご存知の通り、Google等の検索サービスは「クローラー」というプログラムを用いて各ウェブサイトの情報を収集し、それを基に検索結果を利用者に表示しています。

元来、そのクローラーはウェブサイト内の静的なHTMLの情報を取得しています。

しかし、現在は冒頭の相談のように運用の利便性を上げるためにJSONのデータから情報を生成したり、AngularJSなどのJavascript MVCフレームワークによって構成されたサイトが増えております。
これらのサイトでは、サイト内の重要なコンテンツが静的な情報として存在しておらず、クローラーによる情報収集が適切に行えない問題があります。

いちおう、検索エンジンのクローラーは日々進化しており、Javascriptで生成された情報もクローリングの対象になるような動きもありますが、まだその確実性には疑問が残ります。

そのため「Javascriptでコンテンツを生成するページにはSEO的にデメリットが発生してしまう」ということが一つの事実としてあるわけです。

HTMLスナップショットサーバーの利用

ただ、それを解決する手段が無いわけではありません。

それが今回ご紹介する「HTMLスナップショットをサーバーで提供する」という方法です。

つまりどういうことかと言うと、まずは次の図を見ていただければわかりやすかと思います。

snapshot

これは、ブラウザ上で動的に生成される一般のユーザーの目にうつるものとは別に、スナップショットサーバを用意してそこに静的な情報を置いてクローラーにはそちらから情報を収集させることで、問題なくページ内の情報を読み取らせる、という手法です。

これを実現するには2つの手順が必要です。

1. AJAXクロールスキームサポートの明示化

例えば、
http://www.hoge.com/index.html#fuga
のようなページの場合。
http://www.hoge.com/index.html!#fuga
のようにハッシュフラグメントの前に感嘆符をつけることで「クロールできるAJAXページ」とクローラーに認識されます。

2. HTMLスナップショットをクローラーに提供する

上記のような
http://www.hoge.com/index.html!#fuga
といったURLをクローラーでは
http://www.hoge.com/index.html?escaped_fragment=fuga
のように一時的に変換します。
(これをGoogleでは「汚い URL」と呼び、変換前のものを「きれいなURL」と呼んでいるようです。)

このURLに対し、HTMLスナップショットをクローラーに提供することで、クローラーの取得が難しい動的な情報が、クローラーの取得が容易な静的な情報として認識することが可能になり、SEO的なデメリットが解決されます。

ハッシュフラグメントが無い場合

例えば、
http://www.hoge.com
のようなページで同じようなことを行いたい場合。
この場合は、メタタグに

<meta name="fragment" content="!">

を追加することで、上記の例と同じくクローラーがこのURLを
http://www.hoge.com?escaped_fragment=
のように一時的に変換し、そこに対してHTMLスナップショットを提供することで正しいクローリングが可能となります。

 

これらの内容はGoogleの公式ドキュメントにも詳しく書かれておりますので、興味がある方はこちらもぜひご参照ください!
AJAX クロール: ウェブマスターおよびデベロッパー向けガイド

便利なツール

レンダリング後のHTMLのスナップショットをとるツールには以下のようなものがあります。

また、これらの機能をサービスとして提供しているところもあるようです。

検証方法

GoogleのウェブマスターツールにあるFetch as Googleを使うことで、想定のコンテンツがちゃんとクローリングされているかは確認が可能です。

 

ここのところ、弊社自社開発のプロトタイピングツールPrott(プロット)のリリースなどでCodepatchの更新が滞っていましたが、今週からまたどんどん更新していきたいと思いますので引き続きよろしくお願いいたします!