
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeGood news - you're on the right track! Let me break down what you need to get ISR working and explain the preview/draft mode setup. No worries about the "wall of text" - these are great questions.
Your content only appears after redeploying because while you have a revalidate timer set, you're likely missing the most efficient approach: on-demand revalidation. Time-based revalidation works, but combining it with on-demand revalidation gives you the best of both worlds.
You're absolutely right to use getStaticProps with ISR instead of getServerSideProps. ISR is the better choice because:
SSR with getServerSideProps would work but requires server computation on every request, which is slower and more expensive.
First, let's get your basic setup working. In your getStaticProps:
export async function getStaticProps() {
const data = await client.fetch(YOUR_QUERY)
return {
props: { data },
revalidate: 60 // Revalidate every 60 seconds
}
}This will update your content every 60 seconds - the first visitor after the revalidate period triggers a regeneration in the background.
Instead of just waiting for a timer, you can use on-demand revalidation to update pages immediately when content changes in Sanity. This is the recommended approach because it gives you immediate updates when editors hit "publish" while reducing unnecessary API requests.
1. Create an API route at pages/api/revalidate.js:
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.REVALIDATE_SECRET) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// Revalidate the specific path
await res.revalidate(req.query.path || '/')
return res.json({ revalidated: true })
} catch (err) {
return res.status(500).send('Error revalidating')
}
}2. Set up a webhook in Sanity (in your project settings at sanity.io/manage) to trigger this API route when content changes. Point the webhook to https://yoursite.com/api/revalidate?secret=YOUR_SECRET&path=/your-page-path. This gives you immediate updates when editors hit "publish" without waiting for your revalidate timer.
This approach lets you use longer revalidate times (or even remove them) while still getting instant updates, reducing API requests and improving performance.
Now for the preview setup - this is separate from ISR and lets editors see unpublished content. You're right that it involves both front and backend, but you don't need a sanity.json file for modern setups!
1. Create a preview-enabled client:
import { createClient } from 'next-sanity'
export const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
apiVersion: '2024-01-01',
useCdn: true,
})
export const previewClient = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
apiVersion: '2024-01-01',
useCdn: false,
token: process.env.SANITY_API_TOKEN, // Read token from Sanity project settings
perspective: 'previewDrafts', // This fetches draft content!
})The perspective: 'previewDrafts' is crucial - it tells Sanity to prioritize draft documents over published versions, allowing you to see unpublished changes.
Important note on perspectives: Sanity offers several perspectives for different use cases:
published - Only published documents (good for production)previewDrafts - Prioritizes drafts over published (perfect for preview mode)raw - Returns everything, both drafts and published2. Create an API route at pages/api/preview.js:
export default function handler(req, res) {
// Check the secret and next parameters
if (req.query.secret !== process.env.PREVIEW_SECRET || !req.query.slug) {
return res.status(401).json({ message: 'Invalid token' })
}
// Enable Preview Mode by setting the cookies
res.setPreviewData({})
// Redirect to the path from the fetched post
res.redirect(req.query.slug)
}3. Update your getStaticProps to use the preview client when in preview mode:
export async function getStaticProps({ preview = false, params }) {
const activeClient = preview ? previewClient : client
const data = await activeClient.fetch(YOUR_QUERY, params)
return {
props: {
data,
preview
},
revalidate: preview ? 0 : 60 // No caching in preview mode
}
}4. Add an exit preview route at pages/api/exit-preview.js:
export default function handler(req, res) {
res.clearPreviewData()
res.redirect('/')
}The preview button in Sanity Studio (using the Presentation tool) is helpful but not necessary. It gives editors a convenient way to jump to previews, but they can also manually visit your preview URL (like /api/preview?secret=YOUR_SECRET&slug=/blog/post-slug).
If you want to add it, you'd configure it in your Studio with the productionUrl setting, but it's purely for convenience.
The @sanity/preview-kit package you mentioned is part of the modern approach to live previews, but for basic preview mode with getStaticProps, you don't strictly need it. The setup I've shown above uses the standard Next.js preview mode with Sanity clients configured for different perspectives.
If you just want published content to update without redeploying:
revalidate value in getStaticProps (set it based on how fresh content needs to be)The time-based revalidation provides a safety net, while webhooks give you instant updates when content changes. This combination is more efficient than relying solely on time-based revalidation.
Hope this clears things up! The key insight is that ISR with on-demand revalidation via webhooks is typically the best approach for keeping content fresh without constant redeployments, and preview mode is a separate feature for viewing unpublished drafts.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store