Sanity의 컨텐츠 미리보기를 Nuxt에서 처리하는 방법

소개


Jamstack에서 페이지는 구축할 때 생성됩니다.그리고 정적 자산을 CDN 네트워크에 배치하여 방문자에게 신속하게 제공할 수 있다.그러나 이러한 방법은 내용 편집기가 내용을 발표하기 전에 미리 보기를 원할 때 서버가 동적으로 페이지를 구축할 수 없다는 것을 의미한다.
그러면 우리는 어떻게 이 문제를 해결합니까?응, 이것은 여전히 혁신을 진행하고 있는 분야이지만, 이미 해결 방안이 존재한다.가장 간단한 해결 방안은 미리보기 배치를 간단하게 생성하는 것이기 때문에 기본적으로 테스트 URL에서 전체 사이트를 재구성한다.재건 시간이 매우 짧은 상황에서만 이런 방법이 가능하다.증량 구축은 이곳의 해결 방안이 될 것이지만, 우리는 아직 하지 못했다.
또 다른 방법은 정적으로 생성된 Nuxt 사이트를 이용하여 완전한 단일 페이지 응용 프로그램으로 융합시키는 것이다.그리고 클라이언트에서 JavaScript를 사용하여 CMS에서 동적으로 컨텐츠를 가져올 수 있습니다.고맙습니다. Nuxt>v2.13은 참신하고 빛나는 기능preview mode으로 우리의 생활을 가볍게 합니다.✨

Nuxt(>v2.13)에서 미리 보기 모드 사용하기

preview.client.js라는 플러그인을 만듭니다.
// plugins/preview.client.js
export default function ({ query, enablePreview }) {
  if (query.preview) {
    enablePreview()
  }
}
맞다그렇습니다!현재 URL에 쿼리 매개변수?preview=true가 포함되어 있으면 enablePreview 메서드가 호출됩니다.그리고 Nuxt는 서버에서 온 데이터를 버리고 클라이언트에서 nuxtServer Init, asyncData와fetch를 호출합니다.
로컬 테스트 미리 보기 모드를 실행하려면 nuxt generate 를 실행한 다음 nuxt start 을 실행해야 합니다.Nuxt는 미리 보기 쿼리 매개 변수를 설정할 때 API를 호출하는 것을 네트워크 탭에서 볼 수 있습니다.

새 페이지 미리 보기


내가 말한 새로운 페이지는 배치된 적이 없는 페이지를 가리킨다.내용 편집기가 새로운 페이지를 미리 보려고 할 때, 우리는 Nuxt가 그에게 404페이지를 표시하기를 원하지 않습니다.generate.fallback 에서 truenuxt.config.js 로 설정하여 SPA 반환을 활성화할 수 있습니다.이제 Nuxt는 404로 기본 설정되지 않으며 CMS에 대한 API 호출을 통해 페이지를 보여 줍니다.
그러나 사이트의 일반 사용자가 404 페이지를 방문할 때, 우리는 여전히 404 페이지를 표시하기를 희망한다.검증 연결은 이런 상황을 위해 설계된 것이다.
저는 보통 모든 slug를 Vuex에 저장하고 (nuxt Server Init 작업을 통해) 갈고리에 저장된 페이지가 있는지 확인합니다.그러나 미리보기 모드에 "이전 해치"를 제공하는 것을 잊지 마십시오.
validate({ params, store, query }) {
    // If FALSE redirect to 404 page
    return (
      query.preview === 'true' || store.state.moviesSlugs.includes(params.slug)
    )
  }

CMS에서 대상 URL 생성


Sanity에서 내용 편집기는 새 탭에서 미리 보려는 페이지의 대상 URL을 열거나 Studio의 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 파일을 만들고 새 부분으로sanity에 추가합니다.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는 React 구성 요소(Sanity는 React SPA)이지만 그 외에 코드는 JavaScript일 뿐이므로 Vue 개발자가 따르기 쉬워야 한다.너는 언제든지 《이지》extensive documentation를 참고할 수 있다.

처리 초안 미리 보기


초안을 추출하지 않았음을 알 수 있습니다.경험이 없는 사용자가 API에서 초고 문서를 볼 수 없기 때문입니다.초고를 미리 보기 위해 가장 간단한 방법은 auth 쿠키를 사용하는 것이다.콘텐츠 편집기가 CMS에 로그인하면 auth cookie는 브라우저의 Sanity에서 자동으로 설정됩니다.건전한 클라이언트를 withCredentials 로 초기화하면 쿠키는 요청마다 전달됩니다.Sanity Dashboard에서 API 점을 허용하는 자격 증명을 잊지 마십시오.
const client = sanity({
  projectId: 'xxxxxxx',
  dataset: 'production',
  useCdn: false,
  withCredentials: true, // Add this line
})
현재 문제는 두 버전 모두 발표된 파일과 초고로 반송된다는 것이다.따라서 초고가 있으면, 우리는 두 개의 대상을 포함하는 수조를 얻고, 기본적인 알파벳 숫자 순서를 사용하며, 어느 버전이 먼저 나타날지 모른다.이것이 바로 우리가 먼저 초고를 얻을 수 있도록 Nuxt 페이지에서 true 필터링 결과를 통과해야 하는 이유입니다.
// _slug.vue
  const movie = await $sanity.fetch(
        "*[_type == 'movie' && slug.current == $slug] | order(_updatedAt desc)[0]",
        {
          slug: params.slug,
        }
      )

초안을 미리 볼 때 내용 검증을 조심하십시오


Sanity Studio에 설정된 검증 규칙은 초안에 영향을 주지 않습니다.따라서 빈 필수 필드가 프런트엔드 미리보기를 손상시키지 않도록 하십시오.이런 상황을 방지하는 간단한 방법은 코드가 중단될 수 있는 곳에 v-if 명령을 추가하는 것이다.
우리가 사전에 검사해야 할 중요한 정보 중 하나는 세그먼트 플러그인이다.이 필드가 설정되어 있지 않으면 미리 보기 옵션을 표시할 수 없습니다.
문서 연관 메뉴에서 미리보기 열기 옵션을 비활성화합니다.
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 프로그램은 서로 다른 페이지를 내비게이션한 후에 미리 보기 모드를 유지한다는 것이다.따라서 내용 편집기는 그의 블로그 게시물을 미리 보고 블로그 목록 페이지로 이동해 그의 게시물 요약이 어떤 모습인지 볼 수 있다.

1마일을 더 달리다🏃


$nuxt를 사용하여 배너를 미리 봅니다.새로 고침


현재 구현 중, 내용 편집기는 미리 보기를 새로 고칠 때 페이지를 다시 불러와야 합니다. (= 전체 Nuxt 응용 프로그램을 다시 초기화합니다.)
새 탭에서 미리 보기를 열 때 문제가 되지 않지만, Sanity Studio의 iframe에서 열 때, 내용 편집기가 전체 CMS를 다시 불러오거나 닫고 다시 열어야 합니다. (페이지의 스크롤 위치를 잃게 됩니다.)
Nuxt v2.9.0에서 슬쩍 예쁜 기능을 추가했고 properly documented 다음에만 컨텍스트 조수_updateDate를 추가했습니다.기본적으로 클라이언트에서 asyncData를 호출하고 가져오는 것을 허용합니다. 완전히 다시 불러올 필요가 없습니다.
이것은 나로 하여금 미리 보기 모드가 활성화될 때 현수막을 표시하는 것을 생각하게 한다.이 배너에는 $nuxt를 호출하는 단추가 포함되어 있습니다.새로 고침내용 편집기는 이 단추를 누르면 미리보기를 새로 고칠 수 있습니다.
다음은 GitHub 재구매입니다. 이 플래카드를 어떻게 실현하는지에 대한 예가 있습니다.클라이언트만 표시하는 플래카드를 포장해야 합니다. 그렇지 않으면 클라이언트와 서버 노드 트리 사이에 일치하지 않고 서버가 충돌할 수 있습니다.
또 다른 배너 구성 요소에 유용한 내장 속성은 $nuxt.refresh 입니다. 미리 보기 모드에 있으면 $nuxt.isPreview 로 돌아갑니다.이것은 우리가 이런 방식으로 조건부 현수막을 쉽게 표시할 수 있다는 것을 의미한다.
<PreviewBanner v-if="$nuxt.isPreview" />

실시간 미리보기 (성배?)


Sanity에서 매번 편집은 실시간으로 저장되고 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를 검색하지 않습니다.만약 문서가 인용되지 않는다면, 건전한 탐지기는 완벽합니다.그렇지 않으면, 가능한 해결 방안은 $nuxt를 호출하는 것입니다.구독 콜백에서 새로 고침:
.subscribe((update) => {
    this.$nuxt.refresh()
 })
그러나 나는 이렇게 하지 말라고 건의한다. 원인은 네 가지가 있다.
  • 콘텐츠 편집기는 정말 실시간 미리보기가 필요합니까?웹 개발자로서 나는 실시간 미리보기에 흥분했지만, 개인적으로 그것이 실천에서 유용한지 의심스럽다.
  • 그것은 비싸질 수 있다.Sanity listen 방법은 WebSockets를 사용하지만, 우리의 실현은 $nuxt를 사용합니다.새로 고침은 Studio에서 키를 누를 때마다 추가 HTTP 요청을 트리거합니다.
  • 내 구현에서 전방에 표시된 내용은 시종 동기화/업데이트 상태에 있다.(이것은 고정된 것일 수도 있다.)
  • 저는 경량급PicoSanity 클라이언트를 사용하는 것을 더 좋아합니다. 이것은 listen 방법을 지원하지 않습니다.
  • 당신의 피드백을 들으니 매우 기쁩니다


    당신은 현수막을 미리 보는 것에 대해 어떤 생각을 가지고 있습니까?당신은 이미 새로운 Nuxt 미리 보기 모드를 사용하고 있습니까?Nuxt 응용 프로그램에서는 일반적으로 Sanity의 미리보기를 어떻게 처리합니까?당신은 내용 편집의 실시간 미리보기가 어떻다고 생각합니까?나는 개인적으로 이성을 내용 편집기로 사용한 적이 없어서 판단하기 어렵다.
    아래의 평론 부분에서 당신의 관점과 경험을 공유합니다!
    모든 코드 세그먼트는 다음 저장소에서 나온다.Room은 새 프로젝트를 초기화할 때 Sanity CLI에서 제공하는 SF 영화 테스트 데이터 세트를 사용합니다.

    모닐 / 영화 사이트


    🍿 단순 Nuxt(전체 정적) + 미리 보기 모드의 건전성


    모닐 / 영화 스튜디오


    🎬 공상 과학 영화 데이터 집합으로 초기화된 건전한 작업실

    좋은 웹페이지 즐겨찾기