useFetch
Fetch data from an API endpoint with a SSR-friendly composable.
This composable provides a convenient wrapper around useAsyncData
and $fetch
.
It automatically generates a key based on URL and fetch options, provides type hints for request url based on server routes, and infers API response type.
useFetch
is a composable meant to be called directly in a setup function, plugin, or route middleware. It returns reactive composables and handles adding responses to the Nuxt payload so they can be passed from server to client without re-fetching the data on client side when the page hydrates.Usage
pages/modules.vue
<script setup lang="ts">
const { data, pending, error, refresh } = await useFetch('/api/modules', {
pick: ['title']
})
</script>
data
, pending
, status
and error
are Vue refs and they should be accessed with .value
when used within the <script setup>
, while refresh
/execute
is a plain function for refetching data.Using the query
option, you can add search parameters to your query. This option is extended from unjs/ofetch and is using unjs/ufo to create the URL. Objects are automatically stringified.
const param1 = ref('value1')
const { data, pending, error, refresh } = await useFetch('/api/modules', {
query: { param1, param2: 'value2' }
})
The above example results in https://api.nuxt.com/modules?param1=value1¶m2=value2
.
You can also use interceptors:
const { data, pending, error, refresh } = await useFetch('/api/auth/login', {
onRequest({ request, options }) {
// Set the request headers
options.headers = options.headers || {}
options.headers.authorization = '...'
},
onRequestError({ request, options, error }) {
// Handle the request errors
},
onResponse({ request, response, options }) {
// Process the response data
localStorage.setItem('token', response._data.token)
},
onResponseError({ request, response, options }) {
// Handle the response errors
}
})
useFetch
is a reserved function name transformed by the compiler, so you should not name your own function useFetch
. Read and edit a live example in Docs > Examples > Advanced > Use Custom Fetch Composable.
Read and edit a live example in Docs > Examples > Features > Data Fetching.
Params
URL
: The URL to fetch.Options
(extends unjs/ofetch options & AsyncDataOptions):method
: Request method.query
: Adds query search params to URL using ufoparams
: Alias forquery
body
: Request body - automatically stringified (if an object is passed).headers
: Request headers.baseURL
: Base URL for the request.timeout
: Milliseconds to automatically abort request
All fetch options can be given a
computed
or ref
value. These will be watched and new requests made automatically with any new values if they are updated.Options
(fromuseAsyncData
):key
: a unique key to ensure that data fetching can be properly de-duplicated across requests, if not provided, it will be automatically generated based on URL and fetch optionsserver
: whether to fetch the data on the server (defaults totrue
)lazy
: whether to resolve the async function after loading the route, instead of blocking client-side navigation (defaults tofalse
)immediate
: when set tofalse
, will prevent the request from firing immediately. (defaults totrue
)default
: a factory function to set the default value of thedata
, before the async function resolves - useful with thelazy: true
orimmediate: false
optiontransform
: a function that can be used to alterhandler
function result after resolvinggetCachedData
: Provide a function which returns cached data. A null or undefined return value will trigger a fetch. By default, this is:key => nuxt.isHydrating ? nuxt.payload.data[key] : nuxt.static.data[key]
, which only caches data whenpayloadExtraction
is enabled.pick
: only pick specified keys in this array from thehandler
function resultwatch
: watch an array of reactive sources and auto-refresh the fetch result when they change. Fetch options and URL are watched by default. You can completely ignore reactive sources by usingwatch: false
. Together withimmediate: false
, this allows for a fully-manualuseFetch
.deep
: return data in a deep ref object (it istrue
by default). It can be set tofalse
to return data in a shallow ref object, which can improve performance if your data does not need to be deeply reactive.dedupe
: avoid fetching same key more than once at a time (defaults tocancel
). Possible options:cancel
- cancels existing requests when a new one is madedefer
- does not make new requests at all if there is a pending request
If you provide a function or ref as the
url
parameter, or if you provide functions as arguments to the options
parameter, then the useFetch
call will not match other useFetch
calls elsewhere in your codebase, even if the options seem to be identical. If you wish to force a match, you may provide your own key in options
.Learn how to use
transform
and getCachedData
to avoid superfluous calls to an API and cache data for visitors on the client.Return Values
data
: the result of the asynchronous function that is passed in.pending
: a boolean indicating whether the data is still being fetched.refresh
/execute
: a function that can be used to refresh the data returned by thehandler
function.error
: an error object if the data fetching failed.status
: a string indicating the status of the data request ("idle"
,"pending"
,"success"
,"error"
).
By default, Nuxt waits until a refresh
is finished before it can be executed again.
If you have not fetched data on the server (for example, with
server: false
), then the data will not be fetched until hydration completes. This means even if you await useFetch
on client-side, data
will remain null within <script setup>
.Type
Signature
function useFetch<DataT, ErrorT>(
url: string | Request | Ref<string | Request> | () => string | Request,
options?: UseFetchOptions<DataT>
): Promise<AsyncData<DataT, ErrorT>>
type UseFetchOptions<DataT> = {
key?: string
method?: string
query?: SearchParams
params?: SearchParams
body?: RequestInit['body'] | Record<string, any>
headers?: Record<string, string> | [key: string, value: string][] | Headers
baseURL?: string
server?: boolean
lazy?: boolean
immediate?: boolean
getCachedData?: (key: string) => DataT
deep?: boolean
dedupe?: 'cancel' | 'defer'
default?: () => DataT
transform?: (input: DataT) => DataT | Promise<DataT>
pick?: string[]
watch?: WatchSource[] | false
}
type AsyncData<DataT, ErrorT> = {
data: Ref<DataT | null>
pending: Ref<boolean>
refresh: (opts?: AsyncDataExecuteOptions) => Promise<void>
execute: (opts?: AsyncDataExecuteOptions) => Promise<void>
error: Ref<ErrorT | null>
status: Ref<AsyncDataRequestStatus>
}
interface AsyncDataExecuteOptions {
dedupe?: 'cancel' | 'defer'
}
type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'