Skip to content

Instantly share code, notes, and snippets.

@rylanharper
Created March 11, 2024 20:36
Show Gist options
  • Select an option

  • Save rylanharper/3ea16d972c391e6f7b3e3825611a4c82 to your computer and use it in GitHub Desktop.

Select an option

Save rylanharper/3ea16d972c391e6f7b3e3825611a4c82 to your computer and use it in GitHub Desktop.
Nuxt3 + Sanity Previews Setup (Pre Visual-Editing)
<script setup>
const query = groq`*[_type == "page" && slug.current == $slug]|order(_updatedAt desc)[0] {
... // your schema data
}`
// Create slug
const route = useRoute()
const params = {
slug: route.params.slug
}
// Fetch content
const { data } = await useSanityData({ query: query, params: params })
</script>
<template>
<div v-if="data" class="page">
// ...
</div>
</template>
import { Iframe } from 'sanity-plugin-iframe-pane'
// Show the correct URL based on the current document
function getPreviewUrl(doc) {
return doc?.slug?.current
? `http://localhost:3000/projects/${doc.slug.current}`
: `${window.location.host}`
}
// Import this into the deskTool() plugin
export const defaultDocumentNode = (S, {schemaType}) => {
// Only show preview pane on `project` schema type documents
switch (schemaType) {
case `project`:
return S.document().views([
S.view.form(),
S.view
.component(Iframe)
.title('Preview')
.options({
url: (doc) => getPreviewUrl(doc) + '?preview=true',
reload: {
button: true
}
})
])
default:
return S.document().views([S.view.form()])
}
}
modules: [
'@nuxtjs/sanity',
'@pinia/nuxt'
],
sanity: {
projectId: process.env.SANITY_PROJECT_ID,
dataset: process.env.SANITY_DATASET,
useCdn: true,
additionalClients: {
preview: {
withCredentials: true,
useCdn: false
}
}
}
// Preview.js plugin
import { useSanityStore } from '@/stores/sanity'
export default defineNuxtPlugin(async () => {
const route = useRoute()
const store = useSanityStore()
const preview = route.query.preview && route.query.preview === 'true'
if (preview) {
store.previewIsActive = true
}
})
import { defineConfig } from 'sanity'
// Plugins
import { deskTool } from 'sanity/desk'
// Schemas
import { structure } from './desk'
import { schemaTypes } from './schemas'
// Previews
import { defaultDocumentNode } from './config/default-document-node'
export default defineConfig({
title: 'My Project',
basePath: '/studio',
projectId: '********',
dataset: 'production',
plugins: [
deskTool({
structure,
defaultDocumentNode
})
],
schema: {
types: schemaTypes
}
})
// Sanity.js Pinia store
import { defineStore } from 'pinia'
export const useSanityStore = defineStore('sanity', {
state: () => {
return {
previewIsActive: false,
sanityClient: undefined
}
}
})
// useSanityData composable
import { useSanityStore } from '@/stores/sanity'
export default async function ({ query, params }) {
// Get reference to the sanity store
const store = useSanityStore()
// Determine the sanity client based on preview state
const sanityClient = store.previewIsActive
? {
client: 'preview',
server: false,
initialCache: false
}
: undefined
// Handle live preview
onBeforeMount(() => {
// Check if live preview is enabled
if (store.previewIsActive) {
// Set up the Sanity client for preview mode
const sanity = useSanity('preview')
const debounceRefresh = debounce(refresh, 800)
try {
// Subscribe to changes in the query and parameters
sanity.client.listen(query, params).subscribe((event) => {
// Delay the refresh for 800ms to avoid excessive updates
debounceRefresh()
})
} catch (error) {
// Handle error
console.error(error)
}
}
})
// Fetch data using `useSanityQuery` and parameters
// https://sanity.nuxtjs.org/getting-started/usage#usesanityquery
const { data, refresh } = await useSanityQuery(query, params, sanityClient)
return { data }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment