以前、チャリティーカンファレンス沖縄 2020 vol.1 フロントエンド編で行なったmicroCMSワークショップの内容を記事にしました。
【ワークショップ情報】
— microCMS|編集者も使いやすい日本製ヘッドレスCMS (@micro_cms) June 16, 2020
「microCMS + NuxtでJamstackブログを作ってみよう」
チャリティーカンファレンス沖縄(オンライン)にて、ワークショップをやります。
Jamstack興味あるけどまだ試してみたことないという方、ぜひご参加ください💡https://t.co/GWtVClDQ3q
このワークショップでは、microCMSとNuxt.jsを組み合わせJamstackなブログを作成することができます。
当時の内容はNuxt v2.13に沿ったものでしたが、本記事では内容をアップデートし、v2.14にて説明を進めます。
1. Nuxtプロジェクトを用意する
$ npx create-nuxt-app microcms-nuxt-jamstack-blog
ここでは設定項目は以下のようにします。
下記のコマンドで開発環境が立ち上がります。
$ cd microcms-nuxt-jamstack-blog
$ npm run dev
localhost:3000
にアクセスすると下記が表示されます。
2. microCMSの用意する
アカウント登録
ログイン
サービスの作成
サービスIDは一度設定すると変更ができないので、慎重に決めましょう。
APIの作成
いよいよBlog用のAPIを用意していきます。
リスト形式を選択します。
タイトル、本文のフィールドを用意します。
コンテンツの作成
適当に内容を入力し、公開します。
コンテンツ一覧画面に戻り、画面右上のAPIプレビューをクリックします。
取得ボタンをクリックし、入力内容がAPI経由で取得できるか確認してください(レスポンスJSONが表示されます)。
3. ブログ一覧を表示する
Nuxtでは pages/
以下に作成したファイルに基づいて自動的にルーティングがされる仕組みになっています。
pages/index.vue
→ 記事一覧pages/about.vue
→ Aboutページpages/_slug/index.vue
→ 記事詳細
記事詳細画面のように動的なページは _slug
のようなディレクトリを間に挟む必要があります。(または _slug.vue
でも良い)
URLからのパスに応じて slug
という変数で値を受け取ることができます。
まずは一覧ページを用意していきます。pages/index.vue
を次のように変更してみましょう。
<template>
<ul>
<li v-for="content in contents" :key="content.id">
<nuxt-link :to="`/${content.id}`">
{{ content.title }}
</nuxt-link>
</li>
</ul>
</template>
<script>
import axios from 'axios'
export default {
async asyncData() {
const { data } = await axios.get(
// your-service-id部分は自分のサービスidに置き換えてください
'https://your-service-id.microcms.io/api/v1/blog',
{
// your-api-key部分は自分のapi-keyに置き換えてください
headers: { 'X-MICROCMS-API-KEY': 'your-api-key' }
}
)
return data
}
}
</script>
microCMSのサービスid、api-keyを置き換えてください。asyncData()
というメソッドはサーバーサイドでもクライアントサイドでも動作可能です。
ここでAPI通信を行うことで、ビルド時の処理やページ遷移時の処理を共通化することができます。
参考:https://ja.nuxtjs.org/guide/async-data/
まず、axiosというHTTP通信用のライブラリをインストールします
$ npm install --save axios
次に、api-keyを設定するためにmicroCMSの管理画面に移動します。サービス設定 > API-KEYから確認ができます。
先ほどのソースコード内のX-API-KEY
のところに値をセットします。
ここまで終えたところで、localhost:3000
にアクセスすると記事一覧が表示されているはずです。
4. ブログ詳細を表示する
次はブログの記事詳細画面を作っていきます。pages/
ディレクトリ以下に _slug/
ディレクトリを作成し、その中に index.vue
を作成します
<template>
<main class="main">
<h1 class="title">{{ title }}</h1>
<p class="publishedAt">{{ publishedAt }}</p>
<div class="post" v-html="body"></div>
</main>
</template>
<script>
import axios from 'axios'
export default {
async asyncData({ params }) {
const { data } = await axios.get(
`https://your-service-id.microcms.io/api/v1/blog/${params.slug}`,
{
headers: { 'X-MICROCMS-API-KEY': 'your-api-key' }
}
)
return data
}
}
</script>
asyncData
の引数のparams
の中にslug
というプロパティが含まれており、こちらにURLからのパスが格納されてきます。
例えば、locahost:3000/fda49da2
にアクセスした場合、slug
にfda49da2
が格納されます。
この値を元にmicroCMSのブログAPIを呼び出し、該当の記事データを取得します。localhost:3000
にアクセスし、記事リンクをクリックすると詳細ページを表示することができます。
5. CSSで見た目を装飾する
microCMSのリッチエディタで記述した内容はHTML形式で取得することができます。
しかし、HTML内にclassを付与することが現状できないので、本文を囲うdivにclassを付与し、タグ指定でcssを書いていきます。
Scssで記述するために、node-sassとsass-loaderをインストールします。
$ npm install node-sass@4.14.1 sass-loader@10.1.1
※ 最新パッケージをインストールしてしまうと、現状では依存パッケージのバージョンエラーが出てしまうため、バージョン指定してインストールを行います
テンプレートファイルにstyleタグを追加し、CSSを書いていきます。
VueはHTMLとCSSそのものを変更している感覚でいじれるので、HTMLとCSSさえ分かっている人であれば雰囲気で書けると思います。
<template>
<main class="main">
<h1 class="title">{{ title }}</h1>
<p class="publishedAt">{{ publishedAt }}</p>
<div class="post" v-html="body"></div>
</main>
</template>
<script>
import axios from 'axios'
export default {
async asyncData({ params }) {
const { data } = await axios.get(
`https://your-service-id.microcms.io/api/v1/blog/${params.slug}`,
{
headers: { 'X-MICROCMS-API-KEY': 'your-api-key' }
}
)
return data
}
}
</script>
<style lang="scss" scoped>
.main {
width: 960px;
margin: 0 auto;
}
.title {
margin-bottom: 20px;
}
.publishedAt {
margin-bottom: 40px;
}
.post ::v-deep {
& > h1 {
font-size: 30px;
font-weight: bold;
margin: 40px 0 20px;
background-color: #eee;
padding: 10px 20px;
border-radius: 5px;
}
& > h2 {
font-size: 24px;
font-weight: bold;
margin: 40px 0 16px;
border-bottom: 1px solid #ddd;
}
& > p {
line-height: 1.8;
letter-spacing: 0.2px;
}
& > ol {
list-style-type: decimal;
list-style-position: inside;
}
}
</style>
6. ビルドして静的ファイルを生成してみる
今まではnpm run dev
で開発していましたが、これはいわゆる開発モードで、デプロイする際はビルドして静的ファイルの形で配置します(Jamstackなので)。
下記のコマンドを叩いて、手元で一旦ビルドしてみましょう。
$ npm run generate
デフォルトでは静的ルーティングパスしか生成されません。/_slug/
のような動的なルーティングには別で設定が必要となります。nuxt.config.js
を編集し、generate項目を付け足します。
ここでは、SSG(スタティックサイトジェネレート)時にどんなパスでどんなファイルを生成するかを指定しています。
axiosのimportを忘れずに!
import axios from 'axios'
export defualt {
// 略
generate: {
async routes() {
const pages = await axios
.get('https://your-service-id.microcms.io/api/v1/blog?limit=100', {
headers: { 'X-MICROCMS-API-KEY': 'your-api-key' }
})
.then((res) =>
res.data.contents.map((content) => ({
route: `/${content.id}`,
payload: content
}))
)
return pages
}
}
}
もう一度 npm run generate
を行うと、各ページが生成されます。
下記のコマンドを叩くことで、dist/
配下に生成されたHTMLをlocalhost上で閲覧できるので、正しくビルドできていることが確かめられます。
$ npm start
7. ファイルをホスティングする
ブログの機能としてはまだまだですが、一旦ホスティングまでやってしまいましょう。
ホスティング先として今回はNetlifyを利用します。
Netlifyを利用するためにはGitHub連携が必要なので、今までの作業内容をGitHubにpushしましょう。
まず、GitHubでリポジトリを作成します。
PUSHします。
$ git init
$ git add .
$ git commit -m 'first commit'
$ git remote add origin your-repository // 自分のリポジトリを入力
$ git push -u origin master
Netlifyにログインします。(未登録の方はSignupお願いします)
new site from git ボタンからサイトを新規作成します。
ビルドコマンド、デプロイ先は下記のように設定します。
以上でNetlifyとGitHubが連携してビルドが開始されます。
ビルドが完了したら、Netlifyにホスティングされます。
8. microCMSとNetlifyを連携する
次は、microCMSのコンテンツを変更したらNetlifyのビルドが走るようにします。
API設定 > Webhook からNetlifyを選択します。
NetlifyのWebhookを用意します。
Netlify側のSettings > Build & deploy > Build hooksから設定可能です。
作成するとエンドポイントが割り当てられます。
これをmicroCMS側のWebhook設定に入力し保存します。
以上で連携完了になります。
microCMS側でコンテンツを作成して、Netlifyに反映されるか試してみましょう。
反映されればJamstack構成の完成です!
9. カテゴリーを追加する
おまけにブログにカテゴリーをつけてみましょう。
カテゴリーをつけるにはコンテンツ参照機能を用います。
まずは新しくカテゴリーAPIを作成します。
次に、ブログの API設定 > APIスキーマ に新しくカテゴリーフィールドを追加します。
種類はコンテンツ参照で、カテゴリーAPIを指定します。
このように設定することで入稿時にカテゴリーが選択できるようになり、APIレスポンスにもデータが含まれた形でレスポンスされます。
詳細画面のテンプレートにカテゴリーを加えてみましょう。
<template>
<main class="main">
<h1 class="title">{{ title }}</h1>
<p class="publishedAt">{{ publishedAt }}</p>
<p class="category">{{ category && category.name }}</p>
<div class="post" v-html="body"></div>
</main>
</template>
実際にブラウザで確認し、カテゴリーが表示されればOKです。
おわりに
microCMSとNuxt.jsを組み合わせてJamstack構成のブログを作成しました。
無事、作成できましたでしょうか?
今後の躓きポイントとしては以下のようなものが挙げられます。
- 一覧画面のページング
- 下書きプレビュー
- 目次作成
- サイトマップ、RSSフィード
- API-KEYを隠す
これらに関しては、別記事で解説していきたいと思います。
-----
microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitter、メールからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします!