How Fetched Data Travels From Server to Client
The Nuxt Payload
useFetch and useAsyncData results serialize into a payload embedded in the SSR HTML so the client hydrates without re-fetching.
What you'll learn
- Inspect the __NUXT__ payload in page source
- Use payload extraction for static sites
- Know which value types serialize safely
The reason useFetch does not double-fetch is the Nuxt payload — a serialized snapshot of all the
data your server already loaded, embedded right in the HTML.
Find It in Page Source
Right-click an SSR page, choose “View source”, and search for <script>window.__NUXT__. You will
see something like:
<script>window.__NUXT__ = {
data: { posts: [{ id: 1, title: 'Hello' }] },
state: {},
serverRendered: true,
config: { /* public runtime config */ }
}</script> When the client bundle starts, it reads this object and seeds every useFetch/useAsyncData cache
with the server-side result.
Serializable Types Only
The payload is JSON-like. Stick to:
- Primitives (string, number, boolean, null)
- Plain objects and arrays
- Dates (Nuxt rehydrates them as Date objects)
- Maps, Sets, BigInts (Nuxt has a richer serializer than JSON.stringify)
Avoid:
- Functions
- DOM nodes
- Class instances with private state
- Circular references
If you need to return something exotic, reshape it into plain JSON in your handler before returning.
Payload Extraction for SSG
On static sites, Nuxt can split the payload into a separate _payload.json file per route. When a
visitor navigates client-side from / to /blog, Nuxt fetches _payload.json for /blog instead
of re-running fetches in the browser:
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
payloadExtraction: true // on by default in Nuxt 3
}
}) This keeps navigation snappy on static deployments while preserving the no-double-fetch guarantee.
Hydration and Mismatches →