こんにちは、柴田です。
Jamstack構成においてはプレビュー画面の表示が一つの躓きポイントだと思います。
プレビュー画面を表示する方法はいくつかありますが、今回は/draft
というプレビュー用のURLを用意する方法をご紹介します。
こちらの記事のコードに機能を追加していきたいと思います。
microCMS + NuxtでJamstackブログを作ってみよう
https://microcms.io/blog/microcms-nuxt-jamstack-blog
前提
プレビュー画面とは下書き状態のコンテンツを閲覧する画面です。
microCMSではコンテンツが「下書き中」ステータスの場合、draftKey
が発行されます。
コンテンツ取得のAPIリクエスト時にクエリパラメータとしてdraftKey
を与えることで下書き中のコンテンツを取得することができます。
また、microCMSにはプレビュー機能があります。
API設定 > 画面プレビューで、「画面プレビュー」ボタンをクリックした際の遷移先URLを指定することができます。
遷移先URLには記事のcontentId
とdraftKey
を動的に埋め込むことが可能です。
この仕組みを利用し、フロントエンド側でURLからcontentId
とdraftKey
を受け取り、microCMSに対してAPIリクエストを行うことで下書き中のコンテンツを取得し、プレビュー画面を表示します。
実装方法
まずはプレビュー用のルーティング(/draft
)を用意します。/pages
配下にdraft.vue
を作成しましょう。
プレビューページにおいては、ビルド時ではなくURLからアクセスされたタイミングでクライアントサイドからAPIリクエストを行います。
よって、asyncData
メソッドではなくcreated
メソッドを用います。
// pages/draft.vue
<template>
<main v-if="data" class="main">
<h1 class="title">{{ data.title }}</h1>
<p class="publishedAt">{{ data.publishedAt }}</p>
<div class="post" v-html="data.body"></div>
</main>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
data: {}
};
},
async created() {
const query = this.$route.query;
if (query.id === undefined || query.draftKey === undefined) {
return;
}
const { data } = await axios.get(
`https://your-service-id.microcms.io/api/v1/blog/${query.id}?draftKey=${query.draftKey}`,
{
headers: { 'X-MICROCMS-API-KEY': 'your-api-key' }
}
)
this.data = data;
},
}
</script>
処理の流れとしては以下のようになります。
1. URLから/draft?id=XXXXXXXX&draftKey=YYYYYYYY
のようにアクセスする
2. this.$route.query
からid
とdraftKey
を受け取る
3. microCMSに対してid
とdraftKey
を用いてAPIリクエストを行う
4. 取得データをテンプレート側に渡して描画する
microCMSの設定
Nuxt側の準備はできたので、次にmicroCMS側の設定を行います。
API設定 > 画面プレビュー で以下のようにURLを設定しましょう。
https://your-service-name.netlify.app/draft/?id={CONTENT_ID}&draftKey={DRAFT_KEY}
これでmicroCMS側の設定も完了です。
コンテンツ編集画面で「画面プレビュー」ボタンをクリックすればプレビューを表示できるようになります。
API-KEYを隠す方法
プレビュー時はクライアントサイドからAPIリクエストを行うため、API-KEYが見えてしまいます。
(※要件によっては特に見えていても問題ないとは思います)
これを隠したい場合は、サーバサイドで一度処理を挟む必要があります。
一例として、Netlify Functionsを利用する方法を紹介します。
Netlify Functionsとは
Netlifyが提供するFaaS(Function as a Service)です。
Functionをクラウド上で実行することができる優れものです。
今回はこちらを利用することで、サーバーレスでサーバーサイドの処理を行なっていきます。
(せっかくJamstackなので、ここでサーバーを建ててしまっては本末転倒です)
環境準備
まずはnetlify-lambdaというパッケージをインストールしましょう。
$ npm install -D netlify-lambda
次に、npmスクリプトで呼び出せるようにpackage.jsonに設定を追記します。
// package.json
// 略
"scripts": {
"function:build": "netlify-lambda build functions/",
"function:serve": "netlify-lambda serve functions/"
}
// 略
また、最終的にFunctionのデプロイ先をnetlify.tomlにて設定します。
// netlify.toml
[build]
functions = "dist/api"
下書き取得用のFunctionを実装
Netlify Functionsはfunctions/
配下のソースコードに対して動作します。
今回はfunctions/draft.js
を作成します。
// functions/draft.js
const axios = require('axios');
exports.handler = async (event) => {
const { id, draftKey } = event.queryStringParameters;
if (!id) {
return {
statusCode: 400,
body: JSON.stringify({
error: 'Missing "id" query parameter',
}),
};
}
return axios
.get(
`https://your-service-id.microcms.io/api/v1/blog/${id}?draftKey=${draftKey}`,
{
headers: { 'X-MICROCMS-API-KEY': 'your-api-key' },
}
)
.then(({ data }) => ({
statusCode: 200,
body: JSON.stringify(data),
}))
.catch((error) => {
return {
statusCode: error.response.status,
body: JSON.stringify(error.response.data),
}
});
};
クライアントから渡されるid
とdraftKey
のほかに、サーバサイドでX-API-KEY
を付加してmicroCMSにAPIリクエストを行います。
この状態でnpm run functions:serve
を実行するとローカル環境(9000番port)でサーバーが起動するので、ブラウザから下記のようにアクセスするとレスポンスとして返却されたJSONが表示されます。
http://localhost:9000/.netlify/functions/draft/?id={記事のcontentID}&draftKey={記事のdraftKey}
次に、フロントからこのNetlify Functionsを呼び出すために、pages/draft.vue
を修正します。
// pages/draft.vue
async created() {
const query = this.$route.query;
if (query.id === undefined || query.draftKey === undefined) {
return;
}
const { data } = await axios.get(
`/.netlify/functions/draft?id=${query.id}&draftKey=${query.draftKey}`,
);
this.data = data;
},
Netlifyにデプロイすると、サイトと同じドメインで通信を行うことができるため、上記のように記述することができます。
また、Netlify Functionsへのリクエストなので、ここでAPI-KEYは不要になります。
一方で、開発時(npm run dev
時)はnpm run functions:serve
によって起動したlocalhost:9000
に対して通信を行いたいですよね。
そこで、Nuxt Proxyを用いて、開発時のみlocalhost:9000
に向き先を変更します。
$ npm i -S @nuxtjs/proxy
nuxt.config.js
にproxyの設定を追加します。
// nuxt.config.js
{
// 略
modules: [
'@nuxtjs/proxy'
],
proxy: {
'/.netlify': 'http://localhost:9000'
},
// 略
}
以上の設定により、開発時はローカルに起動したNetlify Functions経由で下書きが取得できるようになりました。
※ただし、proxyはgenerated/static
モードでは動作しないようです。npm run generage && npm start
時にも動作確認をしたい場合は別の方法を考える必要があります。
デプロイ
最後にNetlifyへのデプロイです。
Jamstackによる静的ファイルのデプロイとNetlify Functionsのデプロイが必要なので、Netlifyには次のようにビルドコマンドを設定します。
以降のデプロイからはFunctionsもデプロイされるようになります。
以上で下書きプレビュー時にもAPI-KEYを隠すという作業は完了です。
おわりに
Nuxt × microCMSのJamstack構成におけるプレビューの実装方法について解説しました。
ヘッドレスCMSの場合でも自前で実装すれば、一般的なCMSのようにプレビュー環境を構築することが可能です。
今回ご紹介したのは一例で、他にもプレビュー用に別環境を建てたり、Nuxt Preview Modeの機能を使ったりする方法もあります。
みなさんも良い実装方法をご存知でしたらブログ等でぜひ発信してみてください。
-----
microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitter、メールからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします!