NuxtとHeadlessCMSで超簡単にSSRなブログを作成する方法を紹介します！！

# この記事の対象者

- Vueの基礎を理解している方
- Nuxtの基礎を理解している方
- HeadlessCMSに興味がある方

## 使用するアーキテクチャ

- Nuxt.js
- Prismic.io

## Why!? Nuxt.js

まずブログで一番大事なことですが・・・
NuxtはSSRに対応しているのでSEOに強い！！！
SPAでもSEOいけるでしょ？？？
諸説ありますが、いけると思います。
ここらへんの話は長くなるので別記事でまとめたいと思います。
話は戻りますが、SSRである安心感とやはりSEOに強い！！！ということでNuxtにアーキテクチャとして選択しました。

## Why!? Prismic

Prismicの最大の魅力は無料でも充分な機能を兼ね備えているところです。
サーバーの容量は100GBまで無料となっており１ヶ月のリクエスト/レスポンスの数が`無制限`なんです！
他の某HeadlessCMSは１ヶ月のリクエスト/レスポンス数が決まっており、それ以上を求める場合は有料になってきます。
簡易的にブログを始めたい！画像はあまり掲載しない！！という方にはPrismic.ioは非常にオススメです。

![スクリーンショット 2020-11-01 9.42.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/1ac62910-bb73-81f8-697c-79e7f58273ba.png)


## Why!? HeadlessCMS

楽なんだもん。

DBのメンテナンスもしなくても良いし。APIも提供してくれるし。
所謂バックエンド部分の工数と開発コストは省けるので超ラッキーです。
実際に実務でもHeadlessCMSでバックエンドの開発コストが大幅に削減できました。
数ヶ月分の人件費云々とか運用管理費とか考えると圧倒的にコストパフォーマンスが良いです。
しかしこれはあくまで一例ですので、必ずしもHeadlessCMSが最適とは限らないです。

## 開発環境の用意

### Nuxt.js

```terminal
yarn create nuxt-app blog
```

今回はSSRができれば良いので`Rendering mode`が`Universal （SSR / SSG）`になっていれば良いです。
![スクリーンショット 2020-11-01 9.24.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/ea10d696-0c46-be39-4248-cde747440410.png)

#### 必要なライブラリをインストールする

```terminal
yarn add @nuxtjs/prismic
```

#### nuxt.config.jsにPrismicの設定を追加する

```javascript
modules: [
  "@nuxtjs/prismic"
],

prismic: {
  endpoint: "https://xxxx.cdn.prismic.io/api/v2"
}
```


### Prismic.io

https://prismic.io/

#### アカウント作成

アカウントが未作成の場合は、作成画面に入力してアカウントを作成します。
![スクリーンショット 2020-11-01 13.30.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/76adddb6-cb9e-2b5b-6615-a0915c561f51.png)


#### カスタム投稿タイプ作成

カスタム投稿タイプからは自由に画面の構成を決めることができます。
スクショの構成はメインビジュアル(Heading Image)とタイトル(title)と本文(body)を設定しています。
![スクリーンショット 2020-11-01 9.32.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/01c9626d-fe60-8c93-adb5-8bd4236bf74a.png)

#### リポジトリを作成する

※ここで決める`Repository Name`はAPI名となります。
一度決めた`Repository Name`は変更できませんが、Display Nameは何度でも変更することは可能です。
![スクリーンショット 2020-11-01 13.38.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/c97b4056-5a85-7356-7a69-71674377ba56.png)

### NuxtからPrismicのAPIに接続する

asyncDataでPrismicのAPIに接続してレスポンスを受け取ったらTemplateに値をPropsとして`渡すだけ`です。
実装自体は`非常に簡単でシンプル`です。
このサンプルは記事のすべてを取得するようになっています。
記事単体、フィルタリング方法についてはPrismic.ioのドキュメントから確認することができます。

https://prismic.io/docs/vuejs/getting-started/prismic-nuxt


**API通信側**

```javascript

async asyncData({ $prismic, error }) {
  try {
    const blogPosts = await $prismic.api.query(
      $prismic.predicates.at("document.type", "articles")
    )
    return {
      articleList: blogPosts.results
    }
  } catch (e) {
    error({ statusCode: 404, message: "Page not found" })
  }
}
```

**親 template**

```vue

<template>
  <main class="main">
    <tags :tag-list="tagList" />
    <Article :article-list="articleList" />
  </main>
</template>
```

**子 template**

```vue

<template>
  <div class="article">
    <nuxt-link
      v-for="(item, index) in articleList"
      :key="index"
      class="article__link"
      :to="`/detail/?pageId=${item.id}`"
    >
      <article class="article__card">
        <div class="article__thumbnail">
          <img
            class="article__image"
            :src="item.data.heading_image.url"
            :alt="item.data.heading_image.url"
          />
        </div>
        <div class="article__description">
          <h2 class="article__title">{{ item.data.title[0].text }}</h2>
          <p class="article__body">
            <template v-for="childItem in item.data.body">
              {{ childItem.text }}
            </template>
          </p>
          <p class="article__tag">#{{ item.tags[0] }}</p>
        </div>
      </article>
    </nuxt-link>
  </div>
</template>

<script>
export default {
  name: "Article",
  props: {
    articleList: {
      type: Array,
      default: () => []
    }
  }
}
</script>
```

## 最後に

Templateを自分で用意するという手間はありますが、
自由にTemplateを作成して自由に表示項目も選択することができます。
Prismic.io（HeadlessCMS）は他の言語のサポートも柔軟にしているので多用な場面で利用することができると思います。
Prismic含めてHeadlessCMS自体の認知度が低いと思うので、この記事をきっかけに興味を持っていただけますと幸いです。