useFetch()
SSR-friendly composable that fetches data and caches it with a unique key.
Syntax
const { data, error, status, refresh, pending } = await useFetch(url, options) Parameters
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Request | Ref | (() => string) | Yes | The request URL. Can be a reactive ref or a function for dynamic requests that re-run when dependencies change. |
options | object | No | Options including `method`, `query`, `body`, `headers`, `key`, `server`, `lazy`, `default`, `transform`, `pick`, `watch`, and `immediate`. Also accepts all `$fetch` (ofetch) options. |
Returns
AsyncData<DataT, ErrorT> — Reactive refs: data, error, status, pending, refresh, execute, clear.
Examples
<script setup lang="ts">
const { data: posts, error } = await useFetch('/api/posts')
</script>
<template>
<p v-if="error">Failed to load</p>
<ul v-else>
<li v-for="p in posts" :key="p.id">{{ p.title }}</li>
</ul>
</template>
<script setup lang="ts">
const id = useRoute().params.id
// Reactive key + transform/pick to reduce payload size
const { data } = await useFetch(`/api/users/${id}`, {
key: `user-${id}`,
pick: ['name', 'email'],
})
</script>
<script setup lang="ts">
const search = ref('')
// Function URL re-runs whenever `search` changes
const { data } = await useFetch(() => `/api/search?q=${search.value}`, {
watch: [search],
})
</script>
Notes
`useFetch` runs on the server during SSR and the result is serialized
into the payload so it is not re-fetched during client hydration. It
must be called in a Nuxt context (setup, plugin, or route middleware).
A key is auto-generated from the file/line and URL; pass an explicit
`key` when the URL is dynamic to avoid mismatches. It is a thin wrapper
around `useAsyncData` + `$fetch`. Use `useLazyFetch` to avoid blocking
navigation.