ブログ構築 4. Contentfulのセットアップ #04
2019年10月12日に更新

ContentfulからAPIを取得してNuxt.jsで記事一覧を表示する

今回達成すること

Contentfulにブログ記事を作成して、Nuxt側で表示するためのセットアップを行います。
また、本番環境のNetlifyにブログ記事を表示する設定も行います。

具体的には、

  1. ConttentfulのSDKを導入
  2. dotenvの導入
  3. 開発環境へ環境変数をセット
  4. ContentfulのAPIを取得する設定
  5. Netlifyへ環境変数をセット

を行います。

Contentfulのサンプル記事を作成する

まずはContentfulにログインして、いくつかサンプル記事を作成しましょう。

ヘッダーメニューの「Content」から作成できます。

Title、Slugなんかは適当に、5つくらい記事を作成してください。

Imageの操作について

  • Create new asset and link

    ここから新規画像をアップロードできます。

    新規Imageをアップロードした場合は、 Imageを「Publish」ボタンで公開にしておいてください。

  • Link existing asset

    これはアップロード済みのMediaを選択するリンクです。

2019-08-30 01-43-06

全ての項目を入力し記事を作成したら、右の「Publish」ボタンから記事を公開状態にします。

こんな感じで記事をいくつか作成したら次へ進みましょう。

2019-08-30 02-01-38

Gitでブランチを作成する

Nuxtで作業を始める前に、ブランチを作成して移動しておきましょう。

$ git checkout -b setup_contentful

ブランチに移動したか確認をとりましょう。

$ git branch

  master
* setup_contentful

OKですね。次!

ContentfulのSDKをインストールする

ContantfulのAPIを取得するためにJavascriptSDKをインストールします。

$ yarn add contentful

インストールが完了したら次に進みましょう。

環境変数を扱うdotenvをインストールする

ContentfulのAPI Keyを環境変数として扱うために@nuxtjs/dotenvをインストールします。

環境変数として扱うことで、漏洩を防ぐことができます。

$ yarn add @nuxtjs/dotenv

公式ガイドにあるようにjsonファイルを作成して環境変数をセットする方法もあります。

このやり方の場合は、必ず.contentful.jsonをGitの管理下から外すようにしてください。

誤って公開リポジトリなんかにpushするとAPI keyが漏洩します。

Integrate Contentful with Nuxt.js

.envファイルを作成する

ルートディレクトリ直下、nuxt.config.jsと同じ階層に.envファイルを作成してください。

app
 ...
 L .env  // 作成
 ...

.envという名のファイルはGitの管理下から外れるよう初期設定されていますので、リポジトリにpushされる心配はありません。

不安な場合は、.gitignoreファイルに以下の記載があるか確認してみましょう。(無い場合は同じように書き足してください)

ここにはGitの管理下から除外するファイル名を記載します。

.gitignore
...
# dotenv environment variables file
.env
...

それでは.envファイルを以下のように編集しましょう。

.env
CTF_SPACE_ID=スペースIDを記入
CTF_BLOG_POST_TYPE_ID=blogPost
CTF_CDA_ACCESS_TOKEN=Delivery APIを記入
CTF_PREVIEW_ACCESS_TOKEN=Preview APIを記入

各APIは、Contentfulのヘッダーメニュー「Settings」>>「API keys」より参照できます。

2019-08-29 23-54-59

dotenvのセットアップ

先ほどインストールした@nuxtjs/dotenvのセットアップを行いましょう。

nuxt.config.jsに追記します。

nuxt.config.js
import colors from 'vuetify/es5/util/colors'

require('dotenv').config() // 追記

export default {
	...
  modules: [
    '@nuxtjs/vuetify',
    '@nuxtjs/axios',
    '@nuxtjs/eslint-module',
    '@nuxtjs/dotenv'				// 追記
  ],
	...
}
  • require('dotenv').config()

    dotenvモジュールを使って.envファイルを読み込むコードです。

    先に読み込む必要があるので、export default前に記入してください。

.envファイルの環境変数をNuxtに登録する

そのままnuxt.config.jsを編集していきます。

envプロパティを追加して、NuxtにContentfulの環境変数を追加します。

nuxt.config.js
{
  ...
  ],
    
	// 追記
  env: {
    // contentful
    CTF_SPACE_ID: process.env.CTF_SPACE_ID,
    CTF_BLOG_POST_TYPE_ID: process.env.CTF_BLOG_POST_TYPE_ID,
    CTF_CDA_ACCESS_TOKEN: process.env.CTF_CDA_ACCESS_TOKEN
  },
	// 追記終了
    
  axios: {},
  ...
}

Contentfulプラグインファイルを作成する

Nuxtにcontentfulのアクセストークンをセットします。

pluginsディレクトリ内にcontentful.jsファイルを作成してください。

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

const config = {
  space: process.env.CTF_SPACE_ID,
  accessToken: process.env.CTF_CDA_ACCESS_TOKEN
}

const client = contentful.createClient(config)

export default client

公式ガイドのコードmodule.exportsではうまく取得できませんでした。

この記事を参考に書き方を少し変更しています。

https://medium.com/js-dojo/how-to-use-asyncdata-to-integrate-contentful-into-nuxt-fbf53ca56fa9

plugins内にファイルを作成したらnuxt.config.jsにも登録する必要があります。

pluginsプロパティに下記のように追記してください。

nuxt.config.js
{
  ...
  plugins: [
    'plugins/vuetify',
    'plugins/contentful'	// 追記
  ],
  ...
}

これでContentfulの初期セットアップは完了です。

index.vueからContentful APIを取得する

では、実際にContentfulからAPIを取得しましょう。

pagesディレクトリのindex.vueを編集していきます。

pages/index.vue
<template>
  <v-container fluid>
    <template v-if="posts.length">
      <ul v-for="(post, i) in posts" :key="i">
        <li>{{ post.fields.title }}</li>
        <ul>
          <v-img
            :src="post.fields.image.fields.file.url"
            :alt="post.fields.image.fields.title"
            :aspect-ratio="16/9"
            max-width="400"
            max-height="225"/>
          <li>{{ post.fields.body }}</li>
          <li>{{ post.fields.publishDate }}</li>
        </ul>
      </ul>
    </template>
    <template v-else>
      投稿された記事はありません。
    </template>
  </v-container>
</template>

<script>
import client from '~/plugins/contentful'

export default {
  async asyncData({ env }) {
    let posts = []
    await client.getEntries({
      content_type: env.CTF_BLOG_POST_TYPE_ID,
      order: '-fields.publishDate'
    }).then(res => (posts = res.items)).catch(console.error)
    return { posts }
  }
}
</script>
  • client.getEntries

    ContentfulからAPIを取得するために用意されたメソッドです。

  • content_type: env.CTF_BLOG_POST_TYPE_ID

    この環境変数には、.envファイルで指定した「blogPost」という文字列が入っています。

    content_typeには、Contentfulで作成したモデルの「Api Identifier」を指定します。

  • order: '-fields.publishDate'

これはAPI取得時の並び順を指定しています。

-をつけると公開日の新しい順に、-を外すと公開日の古い順に並び替えができます。

Nuxtを起動してブラウザで確認

いよいよ確認作業です。

Nuxtを起動して"http://localhost:3000/"にアクセスしましょう。

$ yarn dev

こんな感じで記事が取得できていれば成功です!やった。

2019-08-30 18-08-43

Vuetifyの魔力で見た目をかっこよくする

APIの取得の確認が取れたら、もう少しかっこよくしましょう。

layoutsディレクトリのdefault.vueからcontainerを外します。

layouts/default.vue
<template>
  <v-app>
    <nuxt />
  </v-app>
</template>

<script>
export default {}
</script>

次に、index.vueを以下のように編集してください。

pages/index.vue
<template>
  <v-container fluid>
    <v-row
      justify="center"
    >
      <v-col
        cols="12"
        sm="11"
        md="10"
        xl="8"
      >
        <v-row v-if="posts.length">
          <v-col
            v-for="(post, i) in posts"
            :key="i"
            cols="12"
            sm="6"
            lg="4"
            xl="3"
          >
            <v-card
              max-width="400"
              class="mx-auto"
            >
              <v-img
                :src="post.fields.image.fields.file.url"
                :alt="post.fields.image.fields.title"
                :aspect-ratio="16/9"
                max-height="200"
                class="white--text"
              >
                <v-card-title class="align-end fill-height font-weight-bold">
                  {{ post.fields.title }}
                </v-card-title>
              </v-img>

              <v-card-text>
                {{ post.fields.publishDate }}
              </v-card-text>

              <v-list-item three-line style="min-height: unset;">
                <v-list-item-subtitle>
                  {{ post.fields.body }}
                </v-list-item-subtitle>
              </v-list-item>

              <v-card-actions>
                <v-spacer />
                <v-btn
                  text
                  color="primary"
                >
                  この記事をみる
                </v-btn>
              </v-card-actions>
            </v-card>
          </v-col>
        </v-row>
        <div v-else class="text-center">
          投稿された記事はありません。
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import client from '~/plugins/contentful'

export default {
  async asyncData({ env }) {
    let posts = []
    await client.getEntries({
      content_type: env.CTF_BLOG_POST_TYPE_ID,
      order: '-fields.publishDate'
    }).then(res => (posts = res.items)).catch(console.error)
    return { posts }
  }
}
</script>

投稿記事がカード形式で表示されるようになりました。

ここまでの変更をBitbucketにpushしよう

ターミナルに移動しましょう。

変更をmasterブランチにマージして、Bitbucketにpushしていきます。

$ git add -A
$ git commit -m "get_contentful_API"
$ git checkout master
$ git merge setup_contentful
$ git push

Netlifyに環境変数をセットする

ContentfulのAPI keyを登録した.envファイルは、本番環境にpushされないためNetlify上ではKeyが空っぽの状態です。

そこでNetlifyに環境変数を登録します。

Netlifyヘッダーメニューの「Settings」より、「Build & deploy」>>「Environment」へ移動してください。

2019-08-30 18-38-42

3つの環境変数をセットする

「Edit variables」ボタンから、.envファイルに登録した3つの環境変数をセットしましょう。

CTF_PREVIEW_ACCESS_TOKENは、開発環境でしか利用しないため、ここには登録しません。

2019-08-30 18-43-11

登録が完了したら「Save」ボタンで保存してください。

もう一度deployする

Netlifyのキャッシュが効いているため、まだうまく表示されないと思います。

そこでNetlifyにdeployし直します。

ヘッダーメニュー「Deploys」より、「Trigger deployボタン」 >> 「Clear cache and deploy site」をクリックします。

2019-08-30 18-56-27

さて本番環境でもうまく表示されましたか?

お疲れ様でした。

さて、次回は?

今回はContentfulのブログ記事を本番環境に表示するところまで行いました。

次回はブログの個別ページを用意して、記事を表示していきます。

「この記事をみる」のリンク先の作成ですね。

ついでにアイキャッチ画像が無い場合のエラー回避の方法についても紹介します。

お楽しみに。

現在、カテゴリー「Rails apiとNuxt.jsでSPA開発」のデモアプリを構築中です。記事になるまでもう少々のお時間が必要です。ブログの更新が止まって申し訳ありません。デモアプリの進捗状況は こちらの記事 で随時お伝えしてまいります。
スポンサー広告
次の記事はこちらです
ブログ構築
1. 今回作るアプリケーション
#01
Nuxt.jsとContentfulで作るマイブログ
今日のTweet
スポンサー広告