Nuxt (static mode) + microCMS ブログにプレビューページを追加した話
目次
はじめに
Nuxt (static mode) + microCMS ブログに、nuxt のプレビューモードを使用せずにプレビューページを追加してみました。デプロイ不要で内容を0秒でプレビューする方法を解説します。
(vue 2, nuxt 2 を使用しています)
背景
nuxt.js (static mode) + microCMS で構成されてるブログがあります(当サイトではありません)。
microCMS で記事を書いたあと、 nuxt.js タスクランナーの generate コマンドを実行します。タスクランナーは microCMS の REST API から記事データを取得して静的な HTML に書き出します。その 静的 HTML を S3 などにデプロイすることで公開します。
この方法は SSG (Jamstack) と呼ばれます。閲覧する側から見ると完全に静的な HTML なので圧倒的なパフォーマンスの高さや、セキュリティの懸念が少ない利点があります。一方、 nuxt.js の generate タスクランナーを実行しなければ最新の記事情報を表示することができません。
WordPress のように即時プレビューを表示することが不可であることは、運用において大きな課題になりました。
nuxt.js の プレビューモード について
このような課題に対して、 Nuxt.js では プレビューモード という機能が用意されています。 microCMS でも推奨されています。
Nuxt - プレビューモード
https://nuxtjs.org/ja/docs/features/live-preview/
Preview Modeを使ってコンテンツの下書きプレビューを行う | microCMSブログ
https://blog.microcms.io/nuxt-preview-mode/
生成された静的 HTML の中に特定のクエリが渡された場合、新たにデータを再取得するという手法です。
一見この方法で解決しそうですが、新たな記事を作成する場合に、そのままではページが存在しないので 404 エラーになるという課題があります。ホスティング側でルート設定などをすることも可能ではありますが、ホスティングの設定が増え、 Jamstack のシンプルな利点が損なわれてしまいます。
プレビュー用のページを作成
そこで、クエリから ID を取得し、クライアントサイドでデータを取得することができるプレビュー用のページを作成してみました。
mounted のみを使用した単純な Vue ファイルです。 asyncData を使用してしまうと generate 時に nuxt.js がデータを取得しようとして 404 エラーが発生してしまいます。
<template>
<BlogContent v-if="content" :content="content" />
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
components: { BlogContent },
data() {
return {
content: null as BlogContent | null,
}
},
async mounted() {
const { id } = this.$route.query
const content = await this.$microcms.get({...})
this.content = content
},
})
</script>
このページにアクセスされたら、クライアントサイドからのアクセス時に毎回 mounted が呼び出されます。クエリの id を取得して microCMS のプラグインを呼び出し読み込んでくれます。
本番環境でアクセスできないようにする
プレビューができるページを作成できました。しかし、このファイルを本番環境に公開することは避ける必要があります。
- MicroCMS のアクセストークンが漏洩する
- 下書きのコンテンツが漏洩する
- プレビューページが検索エンジンのクローラーにインデックス付けされてしまう
そのため、本番環境ではページを生成しないように制御します。
nuxt.config.js
const enablePreviewMode = false // プレビューモードを環境変数などで制御
export default {
target: 'static', // static モード
// プレビューモードが有効な場合のみアクセストークンをクライアントサイドに出荷する
publicRuntimeConfig: enablePreviewMode ? publicRuntimeConfig : {},
generate: {
// プレビューモードが無効な場合にプレビューページを作らない
exclude: enablePreviewMode ? [] : [/^\/preview/],
},
}
まとめ
プレビューモードのページを作ることで、Jamstack を維持したまま運用の負荷を大きく下げることができました。