Nuxt.js / Contentful でJAMstackなブログ開発編


福岡から世界中の"むずかしい"を簡単にする株式会社diffeasyCTOの西@_takeshi_24です。

この記事はアドベントカレンダー「diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019」の22日目の記事です。

この記事は前回の「JAMstackなブログ開設にチャレンジ」の続きです。
JAMstackなブログ開発にチャレンジしたい方、是非Qiitaアカウントかtwitterをフォローしていただき、ツッコミやいいね!お願いします!

今回はContentfulで記事を投稿し、Nuxt.jsで表示するところまでを解説します。

Contentful

Contentfulのアカウント作成

まずはContentfulのアカウントを作成します。
Contentfulのアカウント登録ページからアカウントを作成します。
後々GitHubと連携するので、GitHubアカウントで登録してください。

名前や組織名などを入力して登録を完了させてください。

コンテンツを作成

アカウント登録が完了すると、コンテンツ作成に進みますが、画面で2つの選択肢が表示されます。

これは最初にサンプルとして作られるスペースの選択のようです。
今回は左側の「I create content」を選択します。

ちなみに、左が通常のヘッドレスCMSで、右側をクリックすると、Gatsbyのスターターテンプレートが生成されます。

スペースを作成

最初にサンプルスペースがすでに作成されていますが、今回は新規に作成します。

ここではフリープランを選択します。


スペース名を入力して、「Create an empty space.」を選択します。


内容を確認し、スペースを作成します。

コンテンツタイプを登録

ブログの記事、カテゴリーなどのコンテンツタイプを登録します。
ヘッダーメニューの「Content model」をクリックします。

ここではブログの記事を投稿するための、「post」のコンテンツタイプを追加します。

「post」のコンテンツタイプにフィールドを追加していきます。
ブログ記事の場合、「タイトル」「本文」「公開日時」などが必要になります。

フィールドを追加したら、画面右上の「save」ボタンで保存します。

コンテンツを投稿

先ほど登録した「post」コンテンツタイプのコンテンツを投稿します。
ヘッダーメニューの「Content」をクリックします。
「タイトル」「本文」「公開日時」を入力して、画面右の「Publish」をクリックして公開します。

投稿したコンテンツが一覧表示されます。

APIキーの発行

スペースを選択した状態で、ヘッダーメニューのSettings→API keysを開き、画面左上の「Add API key」をクリックします。

鍵が生成されて、「Space ID」と「Content Delivery API - access token」が発行されます。
こちらは後ほど使います。

Nuxt.js

次に、Nuxt.jsでクライアント側のWebアプリケーションを作成します。

Nuxt.jsのインストール

Nuxt.jsのインストールなどは「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発 - 準備編」の記事の、Nuxt.jsの手順を参考にしてください。
※今回は静的サイトを生成するため、SPAモードは選択しないでください。
※こちらの記事では環境ごとに環境変数を切り替えるため、.envではなく、cross-envというパッケージを使います。

$ yarn add cross-env

cross-env導入については、こちらの記事「Nuxt.jsとFirebaseAuthentication/FirebaseUIでログイン認証」を参考にしてください。

Contentfulのパッケージを追加

Nuxt.jsからContentfulのコンテンツにアクセスするために、Contentfulのパッケージを追加します。
リッチテキストを表示するための「@contentful/rich-text-html-renderer」パッケージも追加します。

$ yarn add --dev contentful @contentful/rich-text-html-renderer 

Contentful接続の準備

Contentfulの接続情報をenvファイルに記載します。

env.development.js
module.exports = {
  BASE_URL: 'http://localhost:3000',
  CTFL_SPACE: 'wxxxxxxxxxu',
  CTFL_ACCESS_TOKEN: '7LQxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxNM',
  CTFL_CONTENT_TYPE_POST: 'post'
}

ContentfulSDKをNuxt.jsで利用するために、pluginsにcontentful.jsを追加します。

/plugins/contentful.js
const contentful = require('contentful')

module.exports = {
  createClient() {
    return contentful.createClient({
      space: process.env.CTFL_SPACE,
      accessToken: process.env.CTFL_ACCESS_TOKEN
    })
  }
}

記事一覧ページ

記事一覧を取得します。ContentfulSDKのAPIは以下のリンクを参考にしてください。
https://contentful.github.io/contentful.js/contentful/7.11.3/

/pages/posts/index.vue
<template>
  <section class="container">
    <ul>
      <li v-for="(post, index) in posts" :key="index">
        <nuxt-link :to="`/posts/${post.sys.id}`">{{
          post.fields.title
        }}</nuxt-link>
      </li>
    </ul>
  </section>
</template>
<script>
import { createClient } from '~/plugins/contentful.js'

const client = createClient()
export default {
  async asyncData({ params }) {
    // 記事一覧を取得
    const entries = await client.getEntries({
      content_type: process.env.CTFL_CONTENT_TYPE_POST
    })
    return {
      posts: entries.items
    }
  }
}
</script>

記事詳細ページ

記事詳細ページでは、投稿のリッチテキストをHTMLに変換して表示します。

/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 }) {
    // IDをキーに記事を取得
    const entry = await client.getEntry(params.id)
    return {
      post: entry
    }
  },
  methods: {
    toHtmlString(obj) {
      return documentToHtmlString(obj)
    }
  }
}
</script>

以上で、Nuxt.jsを起動し、http://localhost:3000/posts/ にアクセスすると、記事一覧が表示され、そこのリンクから記事詳細ページが表示されます。

今回は、簡易的な表示ではありますが、Nuxt.jsでContentfulのAPIを利用して記事を表示するところまでできました。
次回はジェネレートした静的サイトを配信する手順について説明します!

Nuxt.js / Contentful / NetlifyでJAMstackなブログ開設」につづく

参考サイト

【入門】Nuxt.js + Contentful + Netlify で始める、JAMstack な CMS 構築