Nuxtで正気から内容プレビューを取り扱う方法


導入


Jamstackでは、ビルド時にページが生成されます.静的資産はそれからCDNネットワークに配備されることができて、訪問者にすぐに貢献します.しかし、このアプローチは、コンテンツエディタがコンテンツを公開する前にそのコンテンツをプレビューしたい場合など、そのページでサーバーが構築できないことを意味します.
では、どのようにしてその問題を解決できますか?さて、これはまだイノベーションが現在起こっているドメインですが、いくつかのソリューションが既に存在します.最も簡単な解決策は、単にプレビュー展開を生成することですので、基本的にテストURLに全体のウェブサイトを再構築します.再構築時間が非常に短いならば、このアプローチは実行可能です.インクリメンタルビルドはここでの解決策になるでしょう.
もう一つのアプローチは、我々の静的に生成されたNuxtウェブサイトが本格的なシングルページアプリケーションに水和するという事実を利用することです.次に、クライアント側でJavaScriptを使用してCMSからコンテンツを動的に取得できます.ありがたいことにnuxt > v 2です.13私たちの生活は、その新しい光沢のある簡単になりますpreview mode . ✨

nuxt ( v 2.13 )でプレビューモードを有効にする


プラグインを作成preview.client.js 次のコンテンツを使用します.
// plugins/preview.client.js
export default function ({ query, enablePreview }) {
  if (query.preview) {
    enablePreview()
  }
}
はい!それだ!URLがクエリparamを含んでいるなら?preview=true , EnablePreviewメソッドが呼び出されます.Nuxtはサーバからデータを破棄し、クライアント側でNuxtServerInit , asyncData , FETCHを呼び出します.
プレビューモードをローカルでテストするにはnuxt generate それからnuxt start . ネットワークタブでNuxtがプレビュークエリパラメータを設定したときにAPIを呼び出すことができます.

ブランニューページのプレビュー


真新しいページによって、私は決して展開されなかったページを意味します.私たちは、彼/彼女が真新しいページをプレビューしたいとき、Nuxtがコンテンツエディタに404ページを示すことを望みません.
我々は設定によってアクティブにすることができますスパフォールバックがありますgenerate.fallback to true インnuxt.config.js . Nuxtは404にデフォルトではなく、CMSにAPI呼び出しを行うことでページをレンダリングしようとします.
しかし、私たちはまだそのようなページを訪問するウェブサイトの通常のユーザーが404ページを表示したい.Validateフックはこの状況のために設計されました.
私が通常することは、VUEX(nuxtserverinitアクションを通して)のすべてのスラグを保存して、ページが存在するならば、Validateフックの店に対してチェックします.しかし、プレビューモードの「エスケープハッチ」を提供することを忘れないでください.
validate({ params, store, query }) {
    // If FALSE redirect to 404 page
    return (
      query.preview === 'true' || store.state.moviesSlugs.includes(params.slug)
    )
  }

CMSのターゲットURLの生成


健全性の中で、コンテンツエディタは、新しいタブでプレビューするページのターゲットURLを開くことができます.また、スタジオで直接Iframe内に表示できます.

新しいタブでプレビューを開く


フォローthese instructions そして、あなたが作成したファイルに以下の内容を加えてください.
export default function resolveProductionUrl(document) {
  // Only show the preview option for documents for which a preview makes sense.
  if (document._type === "movie") {
    return `https://nuxt-sanity-movies.netlify.app/${document.slug.current}/?preview=true`
  }
  return undefined
}

iframeの中のプレビューを示すこと


次のコンテンツを使用してJSファイルを作成し、健全性の新しい部分として追加します.あなたが上でした同じファッションのJSON.
import React from "react"
import S from "@sanity/desk-tool/structure-builder"

const url = "https://nuxt-sanity-movies.netlify.app/"

const WebPreview = ({ document }) => {
  const { displayed } = document
  const targetURL = url + displayed.slug.current + `/?preview=true`

  return (
    <iframe
      src={targetURL}
      frameBorder={0}
      width="100%"
      height="100%"
    />
  )
}

export const getDefaultDocumentNode = ({ schemaType }) => {
  // Conditionally return a different configuration based on the schema type
  if (schemaType === "movie") {
    return S.document().views([
      S.view.form(),
      S.view.component(WebPreview).title("Web Preview"),
    ])
  }
}

export default S.defaults()
WebPreview 反応コンポーネント(健全性は反応スパ)です、しかし、さもなければ、コードはちょうどJavascriptです、そして、Vue開発者に従うのは簡単でなければなりません.あなたは常に健全性を参照することができますextensive documentation .

取り扱いドラフトプレビュー


ドラフトがフェッチされないことに注意してください.理由は、ドラフトドキュメントがAPI上に認証されていないユーザーに表示されないことです.プレビューをプレビューするには、最も簡単な方法はAuth Cookieを使うことです.コンテンツエディターがCMSにログインすると、Auth Cookieが自動的にブラウザでSANityによって設定されます.クライアントが初期化された場合withCredentials 設定するtrue , クッキーはそれぞれのリクエストとともに渡されます.そして、健全なダッシュボードのAPIポイントの資格情報を許可することを忘れないでください.
const client = sanity({
  projectId: 'xxxxxxx',
  dataset: 'production',
  useCdn: false,
  withCredentials: true, // Add this line
})
問題は、両方のバージョンが返されるということです.それで、ドラフトがあるならば、我々は2つのオブジェクトで配列を得て、デフォルト英数字順序を使用して、我々はどのバージョンが最初に来るかについて、わかりません.だからこそ、結果をフィルタリングする必要があるのです_updateDate 我々のnuxtページで、最初にドラフトを得るようにしてください.
// _slug.vue
  const movie = await $sanity.fetch(
        "*[_type == 'movie' && slug.current == $slug] | order(_updatedAt desc)[0]",
        {
          slug: params.slug,
        }
      )

コンテンツの検証に注意してください


SANity Studioで設定されている妥当性検査規則は、ドラフトには影響しません.それで、空の必須のフィールドがフロントエンドプレビューを壊さないことを確認してください.これに対する簡単な方法は、コードが壊れるかもしれない若干のV - IF指令を加えることです.
私たちが事前にチェックする1つの重要な情報はスラグフィールドです.このフィールドが設定されていない場合、プレビューオプションは表示されません.
ドキュメントコンテキストメニューの[開くプレビュー]オプションを無効にします
if (!document.slug?.current) {
   return undefined
}
iframeでは、最良の方法はカスタムHTMLページを表示するだけです.
if (!document.slug?.current) {
    return <h1>Please set a slug to see a preview</h1>
}

もう完了!


私がこの全体のアプローチについて最も好きであるものは、我々が我々のページまたはVue構成要素にいくつかの編集をするだけであるだけであるということです.最初にドラフトを取得するためにフィルタを追加する必要がありますが、残念ですが、私はより良い方法を見つけることができませんでした.
私が気づいた別の興味深い詳細は、一度EnabePreviewメソッドが呼び出されたということです、Nuxtアプリは別のページに移動した後、プレビューモードでご利用いただけます.だから、コンテンツエディタをプレビューすることができます彼のブログのポストし、ブログの一覧ページにどのように彼のポストの難題のように参照してくださいに移動します.

エクストラマイル🏃


Nuxtでプレビュー旗。リフレッシュ


現在の実装では、コンテンツエディターは、プレビューを更新したいときにページを再読み込みする必要があります(= Nuxtアプリケーション全体を再初期化).
プレビューが新しいタブで開かれるとき、これは問題ではありません、しかし、それがScenity StudioでIFrameの中で開かれるとき、我々はコンテンツエディタがCMS全体を再ロードするか、Iframeを閉じて、再開しなければならないことを望みません(そして、したがって、ページの彼らのスクロール位置を失う).
Nuxt v 2で.9.0、気の利いた機能が静かに追加されただけであったproperly documented 後で$nuxt.refresh コンテキストヘルパー.基本的に、クライアント側でasyncdata(およびfetch)を呼び出すことができます.
これはプレビューモードが起動したときにバナーを表示するというアイデアを与えました.そのバナーには、$ nuxtを呼び出すボタンが入っています.リフレッシュ.コンテンツエディタは、プレビューを更新するには、そのボタンをクリックすることができます.
ここでは、このようなバナーを実装する方法についての例を示します.そうでなければ、クライアントノードとサーバノードツリーとの間に不整合があり、水和が壊れます.
バナーコンポーネントに便利な別の組み込みプロパティです$nuxt.isPreview , 返り値true プレビューモードの場合.この方法では簡単にバナーを簡単に表示できます.
<PreviewBanner v-if="$nuxt.isPreview" />

リアルタイムプレビュー(聖杯)


SANITYでは、すべての編集はリアルタイムで保存され、健全なクライアントも、コンテンツの変更に反応するためにリッスンメソッドが付属しています.プレビューするページのマウントフックにリスナーを設定できます.
  mounted() {
    if (this.$route.query.preview)
      this.$sanity
        .listen('*[_type == "movie" && slug.current == $slug][0]', {
          slug: this.$route.params.slug,
        })
        .subscribe((update) => {
      this.movie = update.result
        })
  }
しかし、このメソッドはreferences を返します.あなたの文書が参照を持たないならば、健全性聞き手は完璧です.さもなければ、1つの可能な解決策は$ nuxtを呼ぶことです.購読コールバックでのリフレッシュ
.subscribe((update) => {
    this.$nuxt.refresh()
 })
しかし、私は4つの理由からそれを忠告します.
  • コンテンツエディタは本当にリアルタイムプレビューが必要ですか?ウェブ開発者として、私はリアルタイムプレビューに興奮しています、しかし、私は個人的にそれが実際に非常に役に立つと疑います.
  • それは高価である(財政的に、そして、計算的に).一方、健全性を聞くメソッドは、WebSockets、$ nuxtでの実装を使用します.リフレッシュは、スタジオのすべてのキーストロークで追加のHTTPリクエストを発射します.
  • 私の実装では、フロントエンドに表示される内容は常にステップ/アップデートの背後にありました.(これはおそらく修正されます.)
  • 私はライト級を好むPicoSanity クライアントは、listenメソッドをサポートしていません.
  • この上であなたのフィードバックを聞いてうれしい


    プレビューバナーについてのあなたの考えは何ですか?あなたは既に新しいNuxtプレビューモードを使用していますか?どのように通常、Nuxtアプリで健全性からプレビューを処理するのですか?コンテンツ編集のためのリアルタイムプレビューをどう思いますか?私は個人的にはコンテンツエディタとして健全性を使用したことがないので、私は判断するのは難しい.
    以下のコメントのセクションであなたの意見と経験を共有!
    すべてのコードスニペットは、次のリポジトリから取得されます.スタジオは、新しいプロジェクトを初期化するとき、Simity CLIによって提供されるSF映画テストデータセットを使用します.

    モルニール / 映画ウェブ


    🍿 単純なNuxt(完全な静的な)+プレビューモードで正気


    モルニール / 映画スタジオ


    🎬 SF映画データセットで初期化された健全なスタジオ