--- navigation.title: 'Custom useFetch' title: Custom useFetch in Nuxt description: How to create a custom fetcher for calling your external API in Nuxt 3. --- When working with Nuxt, you might be making the frontend and fetching an external API, and you might want to set some default options for fetching from your API. The [`$fetch`](/docs/api/utils/dollarfetch) utility function (used by the [`useFetch`](/docs/api/composables/use-fetch) composable) is intentionally not globally configurable. This is important so that fetching behavior throughout your application remains consistent, and other integrations (like modules) can rely on the behavior of core utilities like `$fetch`. However, Nuxt provides a way to create a custom fetcher for your API (or multiple fetchers if you have multiple APIs to call). ## Custom `$fetch` Let's create a custom `$fetch` instance with a [Nuxt plugin](/docs/guide/directory-structure/plugins). ::note `$fetch` is a configured instance of [ofetch](https://github.com/unjs/ofetch) which supports adding the base URL of your Nuxt server as well as direct function calls during SSR (avoiding HTTP roundtrips). :: Let's pretend here that: - The main API is https://api.nuxt.com - We are storing the JWT token in a session with [nuxt-auth-utils](https://github.com/atinux/nuxt-auth-utils) - If the API responds with a `401` status code, we redirect the user to the `/login` page ```ts [plugins/api.ts] export default defineNuxtPlugin((nuxtApp) => { const { session } = useUserSession() const api = $fetch.create({ baseURL: 'https://api.nuxt.com', onRequest({ request, options, error }) { if (session.value?.token) { const headers = options.headers ||= {} if (Array.isArray(headers)) { headers.push(['Authorization', `Bearer ${session.value?.token}`]) } else if (headers instanceof Headers) { headers.set('Authorization', `Bearer ${session.value?.token}`) } else { headers.Authorization = `Bearer ${session.value?.token}` } } }, async onResponseError({ response }) { if (response.status === 401) { await nuxtApp.runWithContext(() => navigateTo('/login')) } } }) // Expose to useNuxtApp().$api return { provide: { api } } }) ``` With this Nuxt plugin, `$api` is exposed from `useNuxtApp()` to make API calls directly from the Vue components: ```vue [app.vue] ``` ::callout Wrapping with [`useAsyncData`](/docs/api/composables/use-async-data) **avoid double data fetching when doing server-side rendering** (server & client on hydration). :: ## Custom `useFetch`/`useAsyncData` Now that `$api` has the logic we want, let's create a `useAPI` composable to replace the usage of `useAsyncData` + `$api`: ```ts [composables/useAPI.ts] import type { UseFetchOptions } from 'nuxt/app' export function useAPI( url: string | (() => string), options: Omit, 'default'> & { default: () => T | Ref }, ) { return useFetch(url, { ...options, $fetch: useNuxtApp().$api }) } ``` Let's use the new composable and have a nice and clean component: ```vue [app.vue] ``` ::note This example demonstrates how to use a custom `useFetch`, but the same structure is identical for a custom `useAsyncData`. :: ::callout{icon="i-simple-icons-youtube" color="red" to="https://www.youtube.com/watch?v=jXH8Tr-exhI"} Watch a video about custom `$fetch` and Repository Pattern in Nuxt. :: ::note We are currently discussing to find a cleaner way to let you create a custom fetcher, see https://github.com/nuxt/nuxt/issues/14736. ::