Conteful公式ドキュメント「Integrate Contentful with Nuxt.js」の翻訳

## はじめに
### 対象者

### 前提知識
Vue.js・Nuxt.jsの基本知識があることは前提とします。
※VueやNuxtに自信がない方は以下の本がおすすめです。
<a target="_blank" href="https://www.amazon.co.jp/gp/product/4798056596/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4798056596&linkCode=as2&tag=newt0-22&linkId=04a5898560e3e1a2d126227cef833834">『Vue.js&Nuxt.js超入門』(掌田津耶乃著・秀和システム)</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=newt0-22&l=am2&o=9&a=4798056596" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<a target="_blank" href="https://www.amazon.co.jp/gp/product/B07J5434JB/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B07J5434JB&linkCode=as2&tag=newt0-22&linkId=9de04e3ff7dc1ed4fa9e19f906d7bbe0">『Nuxt.jsビギナーズガイド』(花谷拓磨・ シーアンドアール研究所)</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=newt0-22&l=am2&o=9&a=B07J5434JB" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<a target="_blank" href="https://www.amazon.co.jp/gp/offer-listing/B07GJM9ZRR/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B07GJM9ZRR&linkCode=am2&tag=newt0-22&linkId=a0da9b6c0bfd895e95e5090347cda085">『Hello!! Nuxt.js（Hello!!Vue&amp;Nuxtシリーズ)』 (技術の泉シリーズ（NextPublishing）)</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=newt0-22&l=am2&o=9&a=B07GJM9ZRR" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

### なぜこの記事を書いたのか
Nuxt.jsは、国内でますますの盛り上がりを見せています。特に、ContentfulやMicroCMSといったHeadless CMSと組み合わせたJAMStackな構成が注目されています。
しかし、Headless CMSの中で圧倒的な実績と人気を誇るContentfulはドキュメントが日本語対応していません（※2020年3月24日現在）。Contentfulのドキュメントは（英語とはいえ）この上なく丁寧に解説されています。

そこで、公式ドキュメントの
[Integrate Contentful with Nuxt.js](https://www.contentful.com/developers/docs/javascript/tutorials/integrate-contentful-with-vue-and-nuxt/)
を自分用に日本語に翻訳したものをQiita上で共有させて頂きます。
なるべく原文通りの翻訳を心がけていますが、適宜注をつけています。
参考になれば幸いです。


(※以下本文です)

------

## Integrate Contentful with(ContentfulをNuxt.jsと統合する)

[新しいインタラクティブなCLIの開始ガイド](https://www.contentful.com/developers/docs/tutorials/general/get-started/)を試してみると、おそらく、サーバー側とブラウザーでVue.jsを実行できる[ユニバーサルJavaScriptアプリケーション](https://github.com/contentful/blog-in-5-minutes)であることがわかりました。これは、ビルド時に静的サイトのセット全体を生成し、ユーザーが別の場所に移動したい場合、[Vue.js](https://vuejs.org/)を使用してサイトが部分的に再レン​​ダリングされることを意味します。かなりクールなものです！

このチュートリアルでは、Contentfulを使用して独自のNuxt.jsプロジェクトをセットアップする方法を示します。

### Getting started with Nuxt.js(Nuxt.jsの使用を開始する)

Nuxt.jsアプリケーションで開始する推奨の方法は、vue-cliツールを使用することです。

```
$ npm install -g vue-cli
```

`vue`コマンドが使用可能になったので、`nuxt / starter`テンプレートを使用して新しいプロジェクトを初期化できます。

```
$ vue init nuxt / starter <プロジェクト名>
```

これで、新しく作成したプロジェクトに移動し`npm install`を実行するだけで、ユニバーサルJavaScriptアプリケーションをContentfulに対応させることができます。詳細については、[Nuxt.jsの入門ガイド](https://nuxtjs.org/guide/installation)をご覧ください。`npm run dev`コマンドは、プロジェクト内での開発に使用できます。実行すると、Nuxt.jsサンプルプロジェクトが表示されます。その後、微調整してContentfulを実装できます。

### Setting up the content model using the Contentful CLI(Contentful CLIを使用してコンテンツモデルを設定する)

Contentfulの統合を開始する前にスペースを設定し、コンテンツモデルを作成してデータを入力する必要があります。(あなたにとって）これがまったく新しい場合は、[Contentfulデータモデルの紹介](https://www.contentful.com/developers/docs/concepts/data-model/)と、[コンテンツ作成の完全な初心者向けガイド](https://www.contentful.com/r/knowledgebase/contentful-101/)を最初に読むことをお勧めします。

すべてのデータ設定を手動で行うことができますが、[CLI](https://www.contentful.com/developers/docs/tools/cli/)を使用して新しいスペースを作成し、データをフィードすることもできます。代わりにこれを行いましょう。

CLIは、[提供されている方法](https://www.contentful.com/developers/docs/tutorials/cli/installation/)のいずれかでインストールできます。

CLIを使用できるようになったので、 `contentful login`を介してそれを認証する必要があります。このコマンドは、新しいブラウザウィンドウを開きます。このウィンドウでは、新しいアカウントを作成するか、ログインして新しいアクセストークンを取得できます。

```
$ contentful login
```

新しいスペースの作成は、CLIコマンドを1つ使用するだけで済み、app.contentful.comに手動で移動する必要はありません。

注：[あなたのプラン](https://www.contentful.com/pricing/?faq_category=payments&faq=what-type-of-spaces-can-i-have#what-type-of-spaces-can-i-have/)で使用可能な空きスペースがなくなった場合、スペースを作成すると追加料金が発生する場合があります。

```
$ contentful space create --name 'Nuxt tutorial
```

すごい！これで新しいスペースが作成され、コンテンツをシードする準備ができました。 CLIツールはすぐに必要になるスペースIDを表示します。

スペース間でコンテンツを転送するには[Contentful CLI](https://www.contentful.com/developers/docs/tools/cli/)から`contentful space export`および`contentful space import`コマンドを使用します。

`seed`コマンドは、定義済みの`--space-id`フラグとともに使用できますが、便宜上、次のコマンドにも特定のスペースを使用するようにCLIを構成できます。


```
$ contentful space use
? Please select a space:
  ...
❯ Nuxt tutorial (k8iqtj0xib4n)
  ...
```

いくつかのデータをインポートします！

```
# after space selection using `contentful space use`
$ contentful space seed --template blog
# without space selection
$ contentful space seed --template blog --space-id <your-new-space-id>
```

新しいスペースには、人とブログ投稿のコンテンツタイプを含むコンテンツモデルが設定されました。

最後に行うことは、[Content Delivery API](https://www.contentful.com/developers/docs/references/content-delivery-api/)アクセストークンを作成することです。これは、[Webアプリ](https://www.contentful.com/developers/docs/references/authentication/)またはCLIを使用して実行できます。

```
$ contentful space accesstoken create --name nuxt-tutorial
✨Successfully created access token nuxt (1234567890xxxxxxxxxxx)
```

これは開始してNuxt.jsアプリに統合するのに十分です。

## Integrating Contentful into Nuxt.js(ContentfulをNuxt.jsに統合する)
この時点でNuxt.jsプロジェクトは、`./pages/index.vue`で定義されているルートインデックスのみを使用できます。 Contentfulを使用するには、2つのことを行う必要があります。

- [Contentful JavaScript CDA SDK](https://www.npmjs.com/package/contentful)を登録する
- `index.vue`ページコンポーネントでデータを取得する

### Install the Contentful CDA JavaScript SDK(Contentful CDA JavaScript SDKをインストールします)
Contentfulを使用する最も簡単な方法は、JavaScript SDKをインストールすることです。これを行うには、`npm install contentful`を簡単に呼び出します。 JavaScript SDKはブラウザのJavaScriptバンドルに含まれるので、npm `--save`フラグを使用して実稼働依存関係として保存する必要があります。

```
$ npm install --save contentful
```

Nuxt.jsは、サーバー（静的な事前レンダリング）およびクライアント側（動的な再レンダリング）でカスタムコードを使用できるようにするプラグイン機能を提供します。幸いなことに、JavaScript SDKは[axios](https://github.com/mzabriskie/axios)に基づいており、Node.jsおよびブラウザーコンテキストで使用できます。

これを使用するには、`plugins`ディレクトリに`contentful.js`という新しいファイルを作成します。このファイルの目的は、ブートストラッププロセス中に設定する定義済みの環境変数を使用してSDKクライアントを作成することです。

```
// ./plugins/contentful.js

const contentful = require('contentful')
// use default environment config for convenience
// these will be set via `env` property in nuxt.config.js
const config = {
  space: process.env.CTF_SPACE_ID,
  accessToken: process.env.CTF_CDA_ACCESS_TOKEN
}

// export `createClient` to use it in page components
module.exports = {
  createClient () {
    return contentful.createClient(config)
  }
}
```

次に、使用する環境変数を定義する必要があります。実行中にCLIですべての環境変数を設定する必要性を回避するには`npm run dev`では、`.contentful.json`と呼ばれる新しい構成ファイルをセットアップできます。このファイルには、必要な構成が含まれています。

- 人のエントリID（ブログの所有者）
- 投稿データを取得するブログ投稿のコンテンツタイプID
- あなたのスペースID
- コンテンツ配信アクセストークン

すでにスペースID（`CTF_SPACE_ID`）とアクセストークン（`CTF_CDA_ACCESS_TOKEN`）を使用しています。ブログ投稿のコンテンツタイプIDと、ブログの作成者である1人のエントリIDは、テンプレートデータで既に定義されています。ブログ投稿のIDは`blogPost`になり、perosnのIDは`15jwOBqpxqSAOy2eOO4S0m`になります。

```
{
  「CTF_PERSON_ID」：「15jwOBqpxqSAOy2eOO4S0m」、
  「CTF_BLOG_POST_TYPE_ID」：「blogPost」、
  「CTF_SPACE_ID」：「YOUR_SPACE_ID」、
  「CTF_CDA_ACCESS_TOKEN」：「YOUR_ACCESS_TOKEN」
}
```

`nuxt.config.js`で、構成ファイルを要求し、`env`プロパティを介してプラグインファイルで使用可能にすることができます。

```
// ./nuxt.config.js
const config = require('./.contentful.json')

module.exports = {
  // ...
  env: {
    CTF_SPACE_ID: config.CTF_SPACE_ID,
    CTF_CDA_ACCESS_TOKEN: config.CTF_CDA_ACCESS_TOKEN,
    CTF_PERSON_ID: config.CTF_PERSON_ID,
    CTF_BLOG_POST_TYPE_ID: config.CTF_BLOG_POST_TYPE_ID
  }
  // ...
}
```

[`env`](https://nuxtjs.org/api/configuration-env)プロパティは、Nuex.jsで、Node.jsコンテキストまたはVue.jsコンポーネントのブラウザーの[context object](https://nuxtjs.org/api#context)で実行したときに`process.env`を介して使用できる値を定義する方法です。これは本当に便利になり、その理由がすぐにわかります。

### Fetch data and render every page(データを取得してすべてのページをレンダリングする)
Nuxt.jsは、使用可能なページとルートを定義する規則を定義します。サンプルテンプレートでは、ファイル`./pages/index.vue`が既に作成されています。このファイルは、サイトのエントリポイントになります。動的パラメーターを使用してルーターを定義することもできます。詳細については、[Nuxt.jsルーティングドキュメント](https://nuxtjs.org/guide/routing)を読むか、[完成したサンプル](https://github.com/contentful/blog-in-5-minutes/tree/master/pages)のフォルダー構造を確認することをお勧めします。

Nuxt.jsでは、すべてのページコンポーネントの[非同期データ](https://nuxtjs.org/api/)を定義できます。このデータは、ビルド時に取得され、その後すべてのページナビゲーションの前に取得されます。 Vue.jsの[シングルファイルコンポーネントアプローチ](https://vuejs.org/v2/guide/single-file-components.html)に慣れていない場合は、まずファイル構造を理解してください。

```
<template>
  <div>
    <!-- render data of the person -->
    <h1>{{ person.fields.name }}</h1>
    <!-- render blog posts -->
    <ul>
      <li v-for="post in posts">
        {{ post.fields.title }}
      </li>
    </ul>
  </div>
</template>

<script>
  import {createClient} from '~/plugins/contentful.js'

  const client = createClient()

  export default {
    // `env` is available in the context object
    asyncData ({env}) {
      return Promise.all([
        // fetch the owner of the blog
        client.getEntries({
          'sys.id': env.CTF_PERSON_ID
        }),
        // fetch all blog posts sorted by creation date
        client.getEntries({
          'content_type': env.CTF_BLOG_POST_TYPE_ID,
          order: '-sys.createdAt'
        })
      ]).then(([entries, posts]) => {
        // return data that should be available
        // in the template
        return {
          person: entries.items[0],
          posts: posts.items
        }
      }).catch(console.error)
    }
  }
</script>
```

これらの数行は作成したばかりのContentfulプラグインをインポートし、新しいSDKクライアントを作成します。 Nuxt.jsには、プラグインディレクトリの[ショートハンド](https://nuxtjs.org/api/configuration-plugins)も用意されているため、Contentfulプラグイン（`〜/ plugins / contentful.js'）を簡単にインポートできます。

エクスポートされたオブジェクトの`async`プロパティで、必要なデータを取得し、コンポーネントで使用できるデータで解決されるプロミスを返すことができます。この場合、作成日と1人の人物で並べられたブログ投稿を取得しています。そして、これらの呼び出しの設定値は`env`を介して利用できることがわかります。その後、テンプレートのデータにアクセスできます。

サイドノート：理論上は、各ブログ投稿で[リンク](https://www.contentful.com/developers/docs/concepts/links/)されているため、1回のAPI呼び出しを保存できますが、わかりやすくするために、ここでは2回呼び出すことにしました。

Nuxt.jsによって事前にレンダリングされた最初のルートを持つために必要なことはこれだけです。 Contentfulからのより多くのデータでより多くのルートを作成できます。これにより、事前にレンダリングされた複数のHTMLページが表示され、ナビゲーション中にブラウザーで自動的に再レン​​ダリングされます。このプロダクションを準備するには、`npm run generate`を実行してページを静的に生成します。これらのページはデフォルトで`dist`に書き込まれます。

```
$ npm run generate
...
                                Asset       Size  Chunks             Chunk Names
0.nuxt.bundle.19d1fc79d53508bafb3c.js    9.02 kB       0  [emitted]  pages/index
1.nuxt.bundle.073636965192d97508b7.js     2.8 kB       1  [emitted]  layouts/default
vendor.bundle.159c28fcc84fd619b9e6.js     213 kB       2  [emitted]  vendor
  nuxt.bundle.4a191451179ff5f8654a.js    24.5 kB       3  [emitted]  app
     manifest.2b2d08aa839a35d40759.js    1.51 kB       4  [emitted]  manifest
                           index.html  132 bytes          [emitted]
                 client-manifest.json    5.73 kB          [emitted]
...
```

### Sum up(まとめる)
これは、[インタラクティブな入門CLIガイド](https://www.contentful.com/developers/docs/tutorials/general/get-started/)を使用して5分で達成できる簡単なウォークスルーでした。

Nuxt.jsとContentfulを使用すると、運用上の大きなオーバーヘッドなしで、かなり迅速にユニバーサルJavaScriptアプリケーションを作成できます。スタックを構築して、選択したCDNにプッシュするだけで、準備完了です。

最終的な実装を確認したい場合は、[5分でわかるブログの例](https://github.com/contentful/blog-in-5-minutes)をご覧ください。そこには、いくつかのルートと高度なルートの事前レンダリングを含む完全なソリューションがあります。

楽しんでください！

### 次のステップ
- [JavaScriptアプリでContentful Delivery APIを使用する](https://www.contentful.com/developers/docs/javascript/tutorials/using-js-cda-sdk/)
- [変更されたコンテンツのみを更新する方法](https://www.contentful.com/developers/docs/javascript/tutorials/using-the-sync-api-with-js/)
お探しのものではありませんか？[よくある質問](https://www.contentful.com/faq/)をお試しください。

----

(※以上で翻訳は終了です)