usePreviewSubscription returns null data on last call in catch-all route
This is a common issue with usePreviewSubscription and is typically related to React Strict Mode in development. Here's what's happening:
In development mode, React Strict Mode intentionally double-invokes component renders and effects to help detect side effects. This is why you're seeing multiple calls (4 instead of 2). The null data on the last call is usually part of this lifecycle behavior where the subscription is being torn down and re-established.
Common causes and solutions:
React Strict Mode behavior - This is expected in development. The
nullvalue typically appears during the unmount/remount cycle. In production builds (where Strict Mode doesn't double-invoke), you'll likely see this behavior disappear.Slug parameter timing - With catch-all routes like
[[...slug]].tsx, theslugparameter might beundefinedinitially during hydration, causing the subscription to fire with invalid params. Make sure you're handling this:
const test = usePreviewSubscription(routeQuery, {
params: { slug: slug || '' }, // or slug?.join('/') for array slugs
initialData: data,
enabled: preview && !!slug, // double-bang ensures truthy check
});- Guard against null data - Always handle the
nullcase defensively:
const displayData = test.data ?? data; // fallback to initialDataModern alternative: If you're starting fresh or can migrate, consider using the Live Content API with defineLive instead of usePreviewSubscription. It's the current recommended approach for real-time preview in Next.js and handles these edge cases more gracefully:
import { defineLive } from 'next-sanity/live'
export const { sanityFetch, SanityLive } = defineLive({
client,
browserToken: token,
serverToken: token,
})The Live Content API is more robust and doesn't have the same subscription lifecycle issues you're experiencing with the older usePreviewSubscription hook. It also works seamlessly with Draft Mode for preview functionality.
Bottom line: The behavior you're seeing is likely normal in development with Strict Mode. Just ensure you're handling null data gracefully with a fallback to your initialData, and it should work fine in production.
Show original thread21 replies
Sanity – Build the way you think, not the way your CMS thinks
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.