Nuxt.js / Contentful  / NetlifyでJAMstackなブログ開設

[繋がらないマッチングプラットフォーム「FLAPTALK」](https://flaptalk.jp)を運営する[株式会社OneSmallStep](https://1smallstep.jp)代表取締役CTOの[@_takeshi_24](https://twitter.com/_takeshi_24)です。

この記事はアドベントカレンダー「[diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/diffeasy24)」の24日目の記事です。

この記事は前回の「[JAMstackなブログ開設にチャレンジ](https://qiita.com/_takeshi_24/items/d8241d5327001d767067)」「[Nuxt.js / Contentful でJAMstackなブログ開発編](https://qiita.com/_takeshi_24/items/7d16dc5d0bc41f5e0779)」の続きです。
JAMstackなブログ開発にチャレンジしたい方、是非Qiitaアカウントか[twitterをフォロー](https://twitter.com/_takeshi_24)していただき、ツッコミやいいね！お願いします！

前回はContentfulで記事を投稿し、Nuxt.jsで表示するところまでを解説しましたが、今回はContentfulへの記事投稿をトリガーにNetlifyでGitHubからNuxt.jsのソースを取得し、静的サイトをジェネレートし、配信するまでを解説します。
<img width="1002" alt="スクリーンショット 2019-12-24 23.01.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/fee3026f-745d-2096-b38b-2338e7a508e4.png">


## Nuxt.jsの修正
Contentfulで記事を取得して生成される動的なルートを静的サイトとして生成するため、nuxt.config.jsを以下のように修正します。

```javascript:nuxt.config.js
import { createClient } from './plugins/contentful.js'
let envSet = {}
if (environment !== 'production') {
  envSet = require(`./env.${environment}.js`)
}

export default {
  //・・・

  generate: {
    routes() {
      const client = createClient()
      return client
        .getEntries({ content_type: process.env.CTFL_CONTENT_TYPE_POST })
        .then((entries) => {
          return entries.items.map((entry) => {
            return {
              route: '/posts/' + entry.sys.id,
              payload: entry
            }
          })
        })
    }
  }
}
```

payloadでentryをセットしていますが、記事詳細ページを生成するときに、再度Contentfulにリクエストを投げて記事を取得せずに、一覧で取得した記事データを利用するためです。
記事ページも以下の通り、payloadがあればそちらからデータを取得するように修正します。

```vuejs:/pages/posts/_id/index.vue
<template>
  <section class="container">
    <h1>{{ post.fields.title }}</h1>
    <v-row>
      <v-col>
        <div v-html="toHtmlString(post.fields.body)"></div>
      </v-col>
    </v-row>
  </section>
</template>
<script>
import { documentToHtmlString } from '@contentful/rich-text-html-renderer'
import { createClient } from '~/plugins/contentful.js'

const client = createClient()
export default {
  async asyncData({ params, payload }) {
    // payloadのデータがあれば、そちらから取得する
    if (payload) return { post: payload }
    const entry = await client.getEntry(params.id)
    return {
      post: entry
    }
  },
  methods: {
    toHtmlString(obj) {
      return documentToHtmlString(obj)
    }
  }
}
</script>

```

修正したらGitHubにpushします。

## Netlifyの構築
### アカウント登録
以下のサイトからNetlifyにアクセスし、アカウント登録がまだの場合は、GitHubアカウントで登録します。
https://app.netlify.com/

### Siteの登録
Sitesを開き、「New site from Git」をクリックします。
<img width="1235" alt="スクリーンショット 2019-12-24 23.40.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/8c84e2d5-0427-cd06-1756-4529298c4538.png">

GitHubを選択します。
<img width="716" alt="スクリーンショット 2019-12-24 23.41.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/1c10c43d-841c-e7ec-02c4-e3dc9c9fd949.png">

リポジトリを選択します。
<img width="718" alt="スクリーンショット 2019-12-24 23.42.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/c75585a7-5516-ea87-0f55-d4ac1516aaee.png">

デプロイするブランチを選択し、
Build command : ```nuxt generate```、Publish directory : ```dist```を入力します。
<img width="716" alt="スクリーンショット 2019-12-24 23.43.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/0c51202b-8e42-6677-718f-9b88cdc1a45e.png">

環境変数ファイルはソース管理から除外しているため、「Show advanced」をクリックし、環境変数を設定します。
<img width="717" alt="スクリーンショット 2019-12-25 0.09.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/45618944-bc96-7984-4110-a97ad826edc6.png">


「Deploy site」をクリックすると、静的サイトの生成が実行され、公開されます。
<img width="589" alt="スクリーンショット 2019-12-24 23.47.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/2764e785-e7e3-b55f-3094-519b14694b13.png">

## Contentfulの記事投稿をトリガーに自動デプロイ
次に、Contentfulに記事が投稿されたら、Netlifyの静的サイト生成とデプロイを自動実行するよう対応します。

### NetlifyでWebhooksのURL発行
Netlifyの「Settings」→「Build & deploy」から「Build hooks」に遷移し、「Add build hook」をクリックします。
<img width="1229" alt="スクリーンショット 2019-12-25 0.34.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/51e13850-3365-0424-ee25-f36ae2432749.png">

Build hook名を入力して、保存します。
<img width="914" alt="スクリーンショット 2019-12-25 0.36.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/f3a68a57-aecc-4154-5204-74c098bef14c.png">

URLが発行されるのでコピーします。

### ContentfulのWebhooks設定
次にContentfulのスペースを開き、「Settings」から「Netlify」の「Add」をクリックします。
<img width="1440" alt="スクリーンショット 2019-12-25 0.41.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/318a84d4-27ff-c876-a832-a9290e221c80.png">

先ほどコピーしたNetlifyのWebhooksのURLを貼り付けて、「Create webhook」をクリックします。
<img width="718" alt="スクリーンショット 2019-12-25 0.42.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/ebeb9ec5-14ac-375f-01ad-0dd26f5018fa.png">

### 記事投稿
記事を投稿すると、Webhookが実行され、Netlifyのdeployが走ります。
<img width="1440" alt="スクリーンショット 2019-12-25 0.44.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/0633d388-a4ad-fa46-134e-8ab1e6e0290a.png">
<img width="1195" alt="スクリーンショット 2019-12-25 0.45.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003/caba3397-a68a-9967-2e5c-7c7ea141b4a9.png">

これで、Contengfulで記事投稿すると、NetlifyにジェネレートされたNuxt.jsの静的サイトがデプロイされます。