intermediate
Data fetching
Fetch data with useFetch, useAsyncData, server routes, keys, pending states, errors, and hydration-aware caching.
`useAsyncData` and `useFetch` run on server during SSR and reuse payload on client when keys match. Keys must be stable and unique per logical query.
<script setup>
const { data, pending, error, refresh } = await useFetch('/api/posts', {
key: 'posts-list',
});
</script>
Server routes (`server/api`) colocate BFF endpoints. Handle `pending` and `error` in templates; `refresh` for manual revalidation.
On interviews: deduplication by key, race between navigation and in-flight fetch, passing cookies/auth on server fetch, and not double-fetching after hydration.
Common pitfalls: missing `key` causing cache collisions, fetching in both page and child without coordination, and secrets in client-visible fetch URLs.
The trade-off is shared SSR payload speed versus mental overhead of stable keys and invalidation rules.
Checklist:
- Stable keys per resource + params.
- Await on server; show pending on client.
- Centralize auth headers in server handlers.
- refresh/invalidate after mutations.