useFetch ​
Reactive Fetch API provides the ability to abort requests, intercept requests before they are fired, automatically refetch requests when the url changes, and create your own useFetch
with predefined options.
TIP
When using with Nuxt 3, this functions will NOT be auto imported in favor of Nuxt's built-in useFetch()
. Use explicit import if you want to use the function from VueUse.
Demo ​
https://httpbin.org/get
https://httpbin.org/delay/10
http://httpbin.org/status/500
isFinished: false isFetching: false canAbort: false statusCode: null error: null data: null
Usage ​
Basic Usage ​
The useFetch
function can be used by simply providing a url. The url can be either a string or a ref
. The data
object will contain the result of the request, the error
object will contain any errors, and the isFetching
object will indicate if the request is loading.
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = useFetch(url)
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = useFetch(url)
Asynchronous Usage ​
useFetch
can also be awaited just like a normal fetch. Note that whenever a component is asynchronous, whatever component that uses it must wrap the component in a <Suspense>
tag. You can read more about the suspense api in the Offical Vue 3 Docs
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = await useFetch(url)
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = await useFetch(url)
Refetching on URL change ​
Using a ref
for the url parameter will allow the useFetch
function to automatically trigger another request when the url is changed.
const url = ref('https://my-api.com/user/1')
const { data } = useFetch(url, { refetch: true })
url.value = 'https://my-api.com/user/2' // Will trigger another request
const url = ref('https://my-api.com/user/1')
const { data } = useFetch(url, { refetch: true })
url.value = 'https://my-api.com/user/2' // Will trigger another request
Prevent request from firing immediately ​
Setting the immediate
option to false will prevent the request from firing until the execute
function is called.
const { execute } = useFetch(url, { immediate: false })
execute()
const { execute } = useFetch(url, { immediate: false })
execute()
Aborting a request ​
A request can be aborted by using the abort
function from the useFetch
function. The canAbort
property indicates if the request can be aborted.
const { abort, canAbort } = useFetch(url)
setTimeout(() => {
if (canAbort.value)
abort()
}, 100)
const { abort, canAbort } = useFetch(url)
setTimeout(() => {
if (canAbort.value)
abort()
}, 100)
A request can also be aborted automatically by using timeout
property. It will call abort
function when the given timeout is reached.
const { data } = useFetch(url, { timeout: 100 })
const { data } = useFetch(url, { timeout: 100 })
Intercepting a request ​
The beforeFetch
option can intercept a request before it is sent and modify the request options and url.
const { data } = useFetch(url, {
async beforeFetch({ url, options, cancel }) {
const myToken = await getMyToken()
if (!myToken)
cancel()
options.headers = {
...options.headers,
Authorization: `Bearer ${myToken}`,
}
return {
options,
}
},
})
const { data } = useFetch(url, {
async beforeFetch({ url, options, cancel }) {
const myToken = await getMyToken()
if (!myToken)
cancel()
options.headers = {
...options.headers,
Authorization: `Bearer ${myToken}`,
}
return {
options,
}
},
})
The afterFetch
option can intercept the response data before it is updated.
const { data } = useFetch(url, {
afterFetch(ctx) {
if (ctx.data.title === 'HxH')
ctx.data.title = 'Hunter x Hunter' // Modifies the response data
return ctx
},
})
const { data } = useFetch(url, {
afterFetch(ctx) {
if (ctx.data.title === 'HxH')
ctx.data.title = 'Hunter x Hunter' // Modifies the response data
return ctx
},
})
The onFetchError
option can intercept the response data and error before it is updated when updateDataOnError
is set to true
.
const { data } = useFetch(url, {
updateDataOnError: true,
onFetchError(ctx) {
// ctx.data can be null when 5xx response
if (ctx.data === null)
ctx.data = { title: 'Hunter x Hunter' } // Modifies the response data
ctx.error = new Error('Custom Error') // Modifies the error
return ctx
},
})
console.log(data.value) // { title: 'Hunter x Hunter' }
const { data } = useFetch(url, {
updateDataOnError: true,
onFetchError(ctx) {
// ctx.data can be null when 5xx response
if (ctx.data === null)
ctx.data = { title: 'Hunter x Hunter' } // Modifies the response data
ctx.error = new Error('Custom Error') // Modifies the error
return ctx
},
})
console.log(data.value) // { title: 'Hunter x Hunter' }
Setting the request method and return type ​
The request method and return type can be set by adding the appropriate methods to the end of useFetch
// Request will be sent with GET method and data will be parsed as JSON
const { data } = useFetch(url).get().json()
// Request will be sent with POST method and data will be parsed as text
const { data } = useFetch(url).post().text()
// Or set the method using the options
// Request will be sent with GET method and data will be parsed as blob
const { data } = useFetch(url, { method: 'GET' }, { refetch: true }).blob()
// Request will be sent with GET method and data will be parsed as JSON
const { data } = useFetch(url).get().json()
// Request will be sent with POST method and data will be parsed as text
const { data } = useFetch(url).post().text()
// Or set the method using the options
// Request will be sent with GET method and data will be parsed as blob
const { data } = useFetch(url, { method: 'GET' }, { refetch: true }).blob()
Creating a Custom Instance ​
The createFetch
function will return a useFetch function with whatever pre-configured options that are provided to it. This is useful for interacting with API's throughout an application that uses the same base URL or needs Authorization headers.
const useMyFetch = createFetch({
baseUrl: 'https://my-api.com',
options: {
async beforeFetch({ options }) {
const myToken = await getMyToken()
options.headers.Authorization = `Bearer ${myToken}`
return { options }
},
},
fetchOptions: {
mode: 'cors',
},
})
const { isFetching, error, data } = useMyFetch('users')
const useMyFetch = createFetch({
baseUrl: 'https://my-api.com',
options: {
async beforeFetch({ options }) {
const myToken = await getMyToken()
options.headers.Authorization = `Bearer ${myToken}`
return { options }
},
},
fetchOptions: {
mode: 'cors',
},
})
const { isFetching, error, data } = useMyFetch('users')
If you want to control the behavior of beforeFetch
, afterFetch
, onFetchError
between the pre-configured instance and newly spawned instance. You can provide a combination
option to toggle between overwrite
or chaining
.
const useMyFetch = createFetch({
baseUrl: 'https://my-api.com',
combination: 'overwrite',
options: {
// beforeFetch in pre-configured instance will only run when the newly spawned instance do not pass beforeFetch
async beforeFetch({ options }) {
const myToken = await getMyToken()
options.headers.Authorization = `Bearer ${myToken}`
return { options }
},
},
})
// use useMyFetch beforeFetch
const { isFetching, error, data } = useMyFetch('users')
// use custom beforeFetch
const { isFetching, error, data } = useMyFetch('users', {
async beforeFetch({ url, options, cancel }) {
const myToken = await getMyToken()
if (!myToken)
cancel()
options.headers = {
...options.headers,
Authorization: `Bearer ${myToken}`,
}
return {
options,
}
},
})
const useMyFetch = createFetch({
baseUrl: 'https://my-api.com',
combination: 'overwrite',
options: {
// beforeFetch in pre-configured instance will only run when the newly spawned instance do not pass beforeFetch
async beforeFetch({ options }) {
const myToken = await getMyToken()
options.headers.Authorization = `Bearer ${myToken}`
return { options }
},
},
})
// use useMyFetch beforeFetch
const { isFetching, error, data } = useMyFetch('users')
// use custom beforeFetch
const { isFetching, error, data } = useMyFetch('users', {
async beforeFetch({ url, options, cancel }) {
const myToken = await getMyToken()
if (!myToken)
cancel()
options.headers = {
...options.headers,
Authorization: `Bearer ${myToken}`,
}
return {
options,
}
},
})
Events ​
The onFetchResponse
and onFetchError
will fire on fetch request responses and errors respectively.
const { onFetchResponse, onFetchError } = useFetch(url)
onFetchResponse((response) => {
console.log(response.status)
})
onFetchError((error) => {
console.error(error.message)
})
const { onFetchResponse, onFetchError } = useFetch(url)
onFetchResponse((response) => {
console.log(response.status)
})
onFetchError((error) => {
console.error(error.message)
})
Source ​
Contributors ​
Changelog ​
v10.4.0
on 8/25/2023v10.3.0
on 7/30/2023v10.1.1
on 5/1/2023v10.0.0-beta.4
on 4/13/20234d757
- feat(types)!: rename MaybeComputedRef
to MaybeRefOrGetter
10e98
- feat(toRef)!: rename resolveRef
to toRef
0a72b
- feat(toValue): rename resolveUnref
to toValue
v10.0.0-beta.0
on 3/14/2023v9.13.0
on 2/18/2023c2bc6
- fix: check if it's object for isFetchOptions
v9.9.0
on 12/23/2022v9.5.0
on 11/9/2022v9.3.1
on 10/17/2022v9.0.1
on 7/29/2022v8.9.1
on 7/8/2022v8.9.0
on 7/6/2022v8.7.0
on 6/16/20228f541
- fix: ssr compactible for headersToObject
v8.5.0
on 5/16/2022