NuxtJS と Firebase で SPA を作って Google にインデックスしてもらった時のメモ

こないだ 読書ノートアプリをシングルページアプリケーションとしてつくったときに、そういえば Google って JavaScript が実行されないと成立しないコンテンツはインデックスしてくれないんじゃなかったっけ? という10年前の SEO の知識で思ったときのはなし。

少し調べてみると「今時のクローラーは JavaScript くらい実行して、実行結果をインデックスしてくれんだぜ」という情報が結構あって安心してると「いや、でもそれって完全じゃないから作り方によってはインデックスされないよ」という情報もあって、どっちが正しいんだろうと思いながらアプリを公開してみたところ、不完全にインデックスされて、あれ、なんでだろうなんて思っていろいろ試してみたのでその時のはなしをまとめてみる。

Search Console に登録するためサイトの所有権を確認する HTML をどこ置いたら良いかわからない問題

そもそものはなし
/page/ の中に入れちゃうとファイルとしては出力されないしどうしたらいいんだろう? と思ったら、単に /static/ の中に入れて build すると中のファイルがまんま /dist/ 直下に保存されるのでそれだけだった。まあ、当たり前なんでしょうけど。ググっても出てこなかったので。

リロードすると 404 になる問題

SPA はリロードすると 404 になる。別に実体があるわけじゃなくルーティングでそのように見せているだけなので起点となる URL 以外でリロードするとファイルがないので 404 になる。

そうして当然 404 の URL は Google にインデックスされないので困る。

しかしないものはないので、リライトするしかない。そこで Firebase Hosting を使っている場合、リライトルールで存在しない URL は全部起点となる URL で受け取って処理してもらうようにする。

"hosting": {
 "rewrites": [ { "source": "**", "destination": "/index.html" } ]
}

Apache なら htaccess とかで mod_rewire を使えばいいと思う。

これで一安心。Search Console で URL 検査してみるインデックスはできるようになった。

なんか不完全な形でインデックスされたりインデックスされない問題

これは作り方の問題だったのでだけれど、いざ検索結果をみると、タイトルの一部が抜けていたり、 Firestore から読み込んでいるデータの部分がごっそり抜けている。

原因としては Vue.js の createdmounted のタイミングでフェッチしていたせいだった。created や mounted だと DOM が生成される直前・直後で走るので、DOM が生成される前に非同期でデータを準備取得しておく必要がある。

対応としてはデータをフェッチするタイミングを asyncData に変えた。今のところこれで問題なさそう。

これで無事インデックスされた