【コードある】Nuxt + WordPress  で  netlify 運用が爆速すぎて神だった

まずは作ったサイトを貼っておきます。
https://wp-nuxt-for-netlify.netlify.com/

いかがですか？現在住んでいるオーストラリアのADSLな爆遅回線でも、爆速です。

WordPress は heteml のレンタルサーバーですよ？

感動しすぎたので、徒然なるままに〜。

# ざっくり構成
##  WordPress側
- リニューアル中の家族ブログ（ https://nishida.lol ）
- Heteml レンタルサーバー（月額 2000円）
- Heteml で無料SSL
- WP REST API でGET APIだけ利用 https://v2.wp-api.org/

## フロント側 Nuxt
- Nuxt.js 1.0.0
- `nuxt generate` で静的ファイル生成
- netlify にホスティング https://www.netlify.com/ 


![WP - Nuxt - Netlify.jpg](https://qiita-image-store.s3.amazonaws.com/0/6531/87f93992-d0c6-6574-aaf9-f53e741fb681.jpeg)

GitHub 上で `nuxt generate` する訳ではないので、正確にはちょっと図が鬼のように間違っているのですが、、 GitHub に push された特定のブランチのコードもとに、`nuxt generate` をして静的ファイルを生成、そしてその Build された静的ファイルが netlify でホスティングされるよ！という構成です。

1. WP REST APIで取得してきたデータでローカルでいい感じに Nuxt.js で開発。楽しいですね。
2. Github に push すると Netlify の爆速！！ :D 
3. WordPress を更新しても, 静的ファイル再ビルドで、動的ちっくに更新可能！

的な感じで、作っております。

なんですが、静的ファイルを動的な WP とどう連携して生成しているの？というところを今日は書きます。

# とにもかくにも netlify が神
まずは、netlify が、どれだけ素晴らしいか。爆速は正直 netlify ありきです。
細かくはググって上にでてきたこちらの Qiita 記事などを御覧ください。
https://qiita.com/TakahiRoyte/items/b7c4d1581df1a17a93fb

> - 完全にスケーラブルなサーバー
> - グローバルなCDN（日本拠点あり）
> - SPA向けのプリレンダリング

スケーラブルさや、CDNなど、パフォーマンスがすげーです。
パフォーマンスを然ることながら、簡単お手軽 GitHub 連携（Gitlab や Bitbacketも）や、簡単お手軽ビルドコマンド設定ができます。

ビルド開始や、ビルド結果の Slack 通知もポチポチで、はいっ！終了

とにかく、今月から僕は netlify を愛しているのです

今回は Nuxt.js をつかったので `nuxt generate` という Nuxt.js の静的ファイルを生成するコマンドをビルドコマンドに設定します。

それだけで、指定したブランチに push するだけで、build & deploy がハイパフォーマンスサーバーに決まるのです。

愛が生まれましたね。

# WordPress のデータを generate で組み込む
ただ普通に nuxt.js で build しても netlify は静的ファイルしかホスティングできないので、SSRレンダリングとかそんなことはできません。

ですが、nuxt.js には、`nuxt.config.js` に generate 時に `_article.vue` のような動的ルーティングページも静的ファイル生成してくれる設定をすることができます。

ドキュメントはこちら。https://ja.nuxtjs.org/api/configuration-generate/

genetate: routes() ないで WordPress から情報をひっぱてきて、route パスを配列で返すことで動的ページを静的に書き出せるのです。

``` nuxt.config.js 
  // #LINE 52
  generate: {
    interval: 1000,
    routes () {
      return Promise.all([
        axios.get(`${apiUrl}/wp-json/wp/v2/posts?per_page=100&page=1&_embed=1`),
        axios.get(`${apiUrl}/wp-json/wp/v2/pages?per_page=100&page=1&_embed=1`)
      ]).then((data) => {
        const posts = data[0]
        const pages = data[1]
        return posts.data.map((post) => {
          return {
            route: '/post/' + post.slug,
            payload: post
          }
        }).concat(pages.data.map((page) => {
          return {
            route: page.slug,
            payload: page
          }
        }))
      })
    }
  },
```
https://github.com/yahsan2/wp-nuxt-for-netlify/blob/943004874d1e2a710eca9e65c66823bc04dbc76c/nuxt.config.js#L52

その他に工夫ポイントとしては、２点あります。

## レンタルサーバーが genereate 時に落ちる。

一つ目が 単純に generate コマンドをすると記事数だけ WP API を叩くことになり、たった 30 ~ 40 程度の記事数でも、僕の最愛のレンタルサーバーが 503 の悲鳴をあげて死にました。

そこで上記コードにもある通り、 `general:` には `interval` を指定してあげることで、APIのタイミングを感覚をあけることができ、ちゃんとすべての記事分静的生成ができます。

## generate での build が遅すぎる

上記で落ちなくはなったのですが、記事ごとに `_article.vue` ないで API を叩いているものですから、とっても build が遅かったのです。

実は、routes() は、単純なパスの string の他に、`{payload}` を含んだオブジェクトを返すこともできます。

``` nuxt.config.js 
          return {
            route: '/post/' + post.slug,
            payload: post
          }
```

すると、asyncData() で payload を受けることができるので、payload があれば、payloadのデータを使い、APIで情報を取得しにいくといったことが `_article.vue` でできます。

```js:_article.vue
  async asyncData ({ app, store, params, route, payload }) {
    store.commit('setCurrentPath', route.path)
    const query = {
      slug: params.article,
      _embed: 1
    }
    if (!store.state.cachePosts[params.article]) {
      const posts = payload ? {data: [app.$api.mapProparty(payload, 'post')]} : await app.$api.get(`/posts`, query)
```
このようにすることで、`nuxt.config.js` の generate で記述した一覧のAPIのみで記事の静的ファイルも生成でき、ビルド速度があがりました。

https://github.com/yahsan2/wp-nuxt-for-netlify/blob/943004874d1e2a710eca9e65c66823bc04dbc76c/pages/post/_article.vue#L55

# WordPress 更新のたびに静的ファイルを生成する
ここまでやれば、GitHub に push すると、WordPress のデータを埋め込んだ状態で静的ファイルを生成 netlify にデプロイされる状態ができます。

しかし、WordPress の情報が組み込まれるのは、build 時の静的ファイルが生成されるときだけです。
なので、WordPress を更新したところで、 Netlify のデータは更新されません。

しかし！ さすが我らが netlify は incoming webhooks があり、特定のURLに POST 送信することで、再 build を外部からすることできるのです。
https://www.netlify.com/docs/webhooks/

そうとなればWordPress の `save_post` のフックをつかって、上記のPOST送信をすれば、記事が更新される度にビルドされます。もちろん、通常WordPress に比べたら反映は遅いですが、爆速を手に入れるメリットには十分な簡単さです。

こちらは簡単なコードですが、WPプラグインにしておいたので、良ければ使ってみてください。
https://github.com/yahsan2/wp-netlify-updater


# この構成の選択の理由について
と、このような構成で WordPress と Nuxt を、netlify で爆速サイトつくることができました。

## なぜ WP にこだわるのか。
そこまでしてなぜ WP にこだわるのかということを箇条書きにしておくと、

- WP の管理画面は、管理画面としては使い勝手がよい
- Headless CMS よりも、カスタマイズも自由
- リニューアル案件の場合、すでに WP で作らているケースも多いので、DB以降の手間がない
- 僕が受託 WordPress 案件、やり過ぎた

が、ほぼ最後の理由ですかね。。？笑

## なぜ Nuxt なのか
- 簡単にさくっと作れる
- component が素敵
- 他のサーバー側でも同じ Nuxt フレームワークを使える

単純な静的サイトだとしても、 WordPress や Headless CMS などブログ系でも、サービスだったとしても、僕は Nuxt します。

同じフロント側を、同じフレームワークで開発できるというのは、かなり僕に取っては魅力的です。

## なぜ netlify なのか
愛してる。

# 最後に

サンプルサイトは、トップから記事ページが異常なほど速いかと思うのですが、実はもうひとつ Nuxt 的に速度を上げる工夫をしています。が、書くの大変なので今回は割愛します。この記事が沢山の人に届けば、、その時また考えます。


サンプルも未完成部分が多いし、そもそもリニューアル中のブログで実運用できてないので、
記事数が 1000 件、 10000 件にならないと見えないこともあるので、またそのあたり試していきます。