WP REST API では1回のリクエストでカテゴリーを全件取得することはできない

タイトルの通りですが、WP REST APIでカテゴリー情報を取得する場合、下記のエンドポイントを使いますよね。

/wp-json/wp/v2/categories

これに対してパラメータ per_page で取得件数を設定できるのですが、実はこのパラメータ、1〜100の数値以外を渡すとエラーになります。

ドキュメントにも取りうる値の範囲は記載されていません
https://developer.wordpress.org/rest-api/reference/categories/

なんとなく語感がget_postsでよく使う posts_per_page に似てるので-1を指定すれば全件取得できそうな気がするのですが、ところがどっこいできません。

おそらくパフォーマンスの問題で無茶な使い方を塞がれてるんだと思うのですが、100件以上になりうる可能性がある場合は、本当に必要なカテゴリーだけをパラメータ include で指定して取得してあげるほうが良さそうです。

それでも100件以上欲しい場合は、パラメータ page でしっかりロジカルにページングする必要がありそうです。

Prerender SPA Plugin を使ってSPAサイトのSEO対策をする

株式会社なすびのウェブサイトは、Vue.jsを用いたSPAで作られています(2017年4月現在)。

コーポレートサイトのような情報の提供に重きを置くサイトで、SPAのアーキテクチャを使うことはSEOの面からあまり適した用途であるとは言えません。

それは、GoogleボットこそJSを実行してからパースしてくれるので問題にはならないのですが、FacebookなどのSNSにシェアされた場合は未だにJSの実行までしてくれないからです。

これを解決するためには、サーバーからのレスポンスでHTMLを返す必要性が絶対的にあるのですが、いかんせんSSRを前提に環境の構築を考えると、サーバサイドでNode.jsを噛ませる必要があったりなど、なかなかに敷居が高いのです。

しかしコーポレートサイトのような、ページ数も動的コンテンツも少ない小規模サイトであれば、プリレンダリングという選択肢もあります。

今回はwebpackプラグインでサクッとプリレンダリングする方法の紹介です。

Prerender SPA Plugin
https://github.com/chrisvfritz/prerender-spa-plugin

このプラグインを使って、webpackのbuild過程で静的HTMLを書き出してしまいます。

// webpack.conf.js
var Path = require('path')
var PrerenderSpaPlugin = require('prerender-spa-plugin')

module.exports = {
  // ...
  plugins: [
    new PrerenderSpaPlugin(
      // Absolute path to compiled SPA
      Path.join(__dirname, '../dist'),
      // List of routes to prerender
      [ '/', '/about', '/contact' ]
    )
  ]
}

上記のように保存先とエンドポイントを設定してbuildすると、下記3ファイルが書き出されます。

/index.html
/about/index.html
/contact/index.html

これらのファイルをウェブサーバーに配置すると、当然下記URLでbuildされたHTMLがレスポンスされるのですが、

http://example.com/
http://example.com/about/
http://example.com/contact/

SPAとしてリンクを辿ってaboutページに遷移すると、URLは /about となります。

/about/about/ は違うファイルを指しているため、この状態でリロードすると404になってしまいます。
これを回避するためには、 /about にリクエストが来たら /about/ へリダイレクトする.htaccessを置いてあげれば良いのです

<ifModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !index
RewriteCond %{REQUEST_URI} !.*\.(css|js|html|png|jpg)
RewriteRule (.*) / [L]
</ifModule>