Draft preview without shipping a token to every visitor
A read token in the browser bundle is readable by everyone who loads the page. Preview does not need one — the Studio is already logged in.

Previewing unpublished content on a statically generated site looks like it needs a server. There is no request to read a draft through, so the obvious fix is a token in the client bundle — which is to say a token published to everybody who visits.
Let the authenticated window do the query
The Studio is already authenticated as the editor. So the preview page fetches nothing at all: the Studio runs the projection and posts the result into the preview window, re-running it on a subscription so the pane updates as the document is saved.
The Studio runs the query; the preview page only renders the answer.
Both ends of a postMessage are untrusted
Anything that can reach a window can post to it, so origins are matched exactly in both directions and the payload stays untrusted until it has been validated. Never post to '*' — the message names a document to serve.
<script setup lang="ts">
// Fetched once, at build time, into the prerendered payload.
const { data } = await useSanityContent<BlogIndexQueryResult>(
blogIndexQuery
)
// Paging and search are derived from it — no second request.
const matching = computed(() =>
(data.value?.posts ?? []).filter(matchesFilters)
)
</script>The remaining case for a browser token
There is one, and it is narrow: a private dataset queried from the browser on purpose. That should be an explicit opt-in with its own environment variable — not something that arrives as a side effect of turning previews on.

Written by
Jordan Hale
Front-end Engineer
Jordan builds front ends that stay fast after launch, and spends most of that time deleting work the browser was never asked to do.


