KurocoとNuxt.jsで、プレビュー画面を構築する

Kurocoを利用したNuxt.jsプロジェクトで、プレビューの利用方法を紹介します。

このページは、KurocoとNuxt.jsでのプロジェクトが構築済みであることを前提としています。 まだ構築していない場合は、こちらを参照してください。

プレビューとは

記事のプレビューを行う機能です。

記事を作成/編集する際に、 記事の内容を更新することなく、 ひとまずWEBページ上での作成/編集後の画面を確認したいときに便利な機能です。

記事編集の[Previewを確認する]ボタンでプレビューすることができ、 [更新する/途中保存する]ボタンによる記事の変更をしていない場合でも、 即時で編集している内容をプレビューできます。

Image (fetched from Gyazo)

この機能は初期状態では動作せず、 各種設定とフロントエンド側のコーディングが必要となります。

この記事では、 KurocoとNuxt.jsでのプロジェクトの内容を変更して、 プレビュー機能を有効化するための手順を紹介します。

プレビューする画面のURLを設定する

コンテンツ定義編集 画面の[プレビューの対象とするページのURL]に、 プレビューする画面のURLを設定します。

ここではhttp://localhost:3000/news画面へリンクするように設定します。

Image (fetched from Gyazo)

下記のうちどちらかのURLが プレビューを確認するボタンのリンク先に設定されます。

  • 相対パスを指定された場合は、[フロントエンドドメイン] + 相対パス のURL
  • プロトコルを含んだURLが指定された場合は、そのURL

リンクには、 新規に生成されたワンタイムトークンを含んだ URLクエリパラメータが付加されます。

${URL}?preview_token=aaaAAA000999&validUntil=1234567890

絶対パス、相対パスについて

画像の例では絶対パスを指定していますが、 相対パスを指定した場合、 例えば[フロントエンドドメイン]が下記の画像の通りで、
Image (fetched from Gyazo)
プレビューの対象とするページのURLが下記の画像のとき、
Image (fetched from Gyazo)
リンク先のURLは、 https://kuroco-dev.web.app/sub/feed/preview/?preview_token=aaaAAA000999&validUntil=1234567890 となります。

[フロントエンドドメイン]は、アカウント設定で確認/変更ができます。

設定の確認

実際にプレビューボタンのリンク先が設定したURLとなっているかを確認します。 設定する内容は、 既存の/newsエンドポイントを踏襲するようにします。

Newsの記事編集画面の、 [Previewを確認する]ボタンをクリックすると、別ページを開きます。

開いた先のページURLが、 http://localhost:3000/news?preview_token=... となっていることが確認できます。

Image (fetched from Gyazo)

プレビュー用のエンドポイントを作成する

プレビュー用の記事データを取得するエンドポイントを作成/設定します。

ワンタイムトークンが発行されるため、認証はNoneを指定してください。

設定項目設定
パスnews/preview
有効/無効Image (fetched from Gyazo) 有効
モデルカテゴリーコンテンツ
モデルTopics
オペレーションpreview
認証None
topics_group_id19

Image (fetched from Gyazo)

APIの設定については、 APIをご確認ください。

フロントエンドの追加修正をする

リンク先URLとなっているページの Nuxt.jsプロジェクトの [index.vue]({Nuxt Project}/pages/news/index.vue)にて、 プレビュー機能からリンクされ画面遷移されてきた場合、 /news/previewにリクエストをするように制御するよう、 コードの内容を変更します。 下記のサンプルコードを[index.vue]に上書きしてください。

index.vue
<template>
  <div>
    <div v-for="n in response.list" :key="n.slug">
      <nuxt-link :to="'/news/'+ n.slug">{{n.ymd}} {{n.subject}}</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {
    async asyncData ({ route, $axios }) {

        const requestNews = async () => {
            const response = await $axios.$get(process.env.BASE_URL + '/rcms-api/2/news');
            return { response };
        };
        const requestNewsPreview = async (previewToken) => {
            const response = await $axios.$get(process.env.BASE_URL + '/rcms-api/2/news/preview' + '?preview_token=' + previewToken);
            return { response: { list: [response.details] } };
        };

        // URLのクエリに、
        // preview_tokenが存在する場合は、previewエンドポイントへ、
        // preview_tokenが存在しない場合は、newsエンドポイントへ、
        // リクエストします。
        try {
            const previewToken = route.query.preview_token;
            return previewToken !== undefined ?
                await requestNewsPreview(previewToken) :
                await requestNews();
        }catch (e) {
            console.log(e.message)
        }
    }
}
</script>


また、修正した差分は下記のようになります。

--- a/pages/news/index.vue
+++ b/pages/news/index.vue
@@ -8,10 +8,26 @@
 
 <script>
 export default {
-    async asyncData ({ $axios }) {
+    async asyncData ({ route, $axios }) {
+
+        const requestNews = async () => {
+            const response = await $axios.$get(process.env.BASE_URL + '/rcms-api/2/news');
+            return { response };
+        };
+        const requestNewsPreview = async (previewToken) => {
+            const response = await $axios.$get(process.env.BASE_URL + '/rcms-api/2/news/preview' + '?preview_token=' + previewToken);
+            return { response: { list: [response.details] } };
+        };
+
+        // URLのクエリに、
+        // preview_tokenが存在する場合は、previewエンドポイントへ、
+        // preview_tokenが存在しない場合は、newsエンドポイントへ、
+        // リクエストします。
         try {
-            const response = await $axios.$get(process.env.BASE_URL + '/rcms-api/2/news')
-            return { response }
+            const previewToken = route.query.preview_token;
+            return previewToken !== undefined ?
+                await requestNewsPreview(previewToken) :
+                await requestNews();
         }catch (e) {
             console.log(e.message)
         }

まとめ

記事の内容を更新する前に、 プレビューを確認するボタンを押して、 編集途中のニュース記事を取得できるようになりました。

Image (fetched from Gyazo)

お探しのページは見つかりましたか?解決しない場合は、問い合わせフォームからお問い合わせいただくか、Slackコミュニティにご参加ください。