You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/3.guide/5.recipes/3.custom-usefetch.md
+36-67Lines changed: 36 additions & 67 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,19 +10,46 @@ The [`$fetch`](/docs/4.x/api/utils/dollarfetch) utility function (used by the [`
10
10
11
11
However, Nuxt provides a way to create a custom fetcher for your API (or multiple fetchers if you have multiple APIs to call).
12
12
13
-
## Custom `$fetch`
13
+
## Recipe: API Client with Auth
14
14
15
-
Let's create a custom `$fetch` instance with a [Nuxt plugin](/docs/4.x/directory-structure/app/plugins).
15
+
Let's say you have an external API at `https://api.nuxt.com` that requires JWT authentication via [nuxt-auth-utils](https://github.com/atinux/nuxt-auth-utils), and you want to redirect to `/login` on `401` responses.
If you need lower-level control, you can create a custom `$fetch` instance with a [Nuxt plugin](/docs/4.x/directory-structure/app/plugins) and either use it with `useAsyncData` directly or pass it to `createUseFetch`.
16
48
17
49
::note
18
50
`$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).
19
51
::
20
52
21
-
Let's pretend here that:
22
-
- The main API is https://api.nuxt.com
23
-
- We are storing the JWT token in a session with [nuxt-auth-utils](https://github.com/atinux/nuxt-auth-utils)
24
-
- If the API responds with a `401` status code, we redirect the user to the `/login` page
Wrapping with [`useAsyncData`](/docs/4.x/api/composables/use-async-data)**avoid double data fetching when doing server-side rendering** (server & client on hydration).
65
-
::
66
-
67
-
## Custom `useFetch`/`useAsyncData`
68
-
69
-
Now that `$api` has the logic we want, let's create a `useAPI` composable to replace the usage of `useAsyncData` + `$api`:
70
-
71
-
```ts [app/composables/useAPI.ts]
72
-
importtype { UseFetchOptions } from'nuxt/app'
73
-
74
-
exportfunction useAPI<T> (
75
-
url:string| (() =>string),
76
-
options?:UseFetchOptions<T>,
77
-
) {
78
-
returnuseFetch(url, {
79
-
...options,
80
-
$fetch: useNuxtApp().$apiastypeof$fetch,
81
-
})
82
-
}
83
-
```
84
-
85
-
Let's use the new composable and have a nice and clean component:
If you want to customize the type of any error returned, you can also do so:
94
-
95
-
```ts
96
-
importtype { FetchError } from'ofetch'
97
-
importtype { UseFetchOptions } from'nuxt/app'
98
-
99
-
interfaceCustomError {
100
-
message:string
101
-
status:number
102
-
}
103
-
104
-
exportfunction useAPI<T> (
105
-
url:string| (() =>string),
106
-
options?:UseFetchOptions<T>,
107
-
) {
108
-
returnuseFetch<T, FetchError<CustomError>>(url, {
109
-
...options,
110
-
$fetch: useNuxtApp().$api,
111
-
})
112
-
}
113
-
```
114
-
115
-
::note
116
-
This example demonstrates how to use a custom `useFetch`, but the same structure is identical for a custom `useAsyncData`.
89
+
Wrapping with [`useAsyncData`](/docs/4.x/api/composables/use-async-data)**avoids double data fetching when doing server-side rendering** (server & client on hydration).
:video-accordion{title="Watch a video about custom $fetch and Repository Pattern in Nuxt"videoId="jXH8Tr-exhI"}
122
-
123
-
::note
124
-
We are currently discussing to find a cleaner way to let you create a custom fetcher, see https://github.com/nuxt/nuxt/issues/14736.
description: A factory function to create a custom useAsyncData composable with pre-defined default options.
4
+
links:
5
+
- label: Source
6
+
icon: i-simple-icons-github
7
+
to: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/asyncData.ts
8
+
size: xs
9
+
---
10
+
11
+
`createUseAsyncData` creates a custom [`useAsyncData`](/docs/4.x/api/composables/use-async-data) composable with pre-defined options. The resulting composable is fully typed and works exactly like `useAsyncData`, but with your defaults baked in.
12
+
13
+
::note
14
+
`createUseAsyncData` is a compiler macro. It must be used as an **exported** declaration in the `composables/` directory (or any directory scanned by the Nuxt compiler). Nuxt automatically injects de-duplication keys at build time.
The resulting composable has the same signature and return type as [`useAsyncData`](/docs/4.x/api/composables/use-async-data), with all options available for the caller to use or override.
description: A factory function to create a custom useFetch composable with pre-defined default options.
4
+
links:
5
+
- label: Source
6
+
icon: i-simple-icons-github
7
+
to: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/fetch.ts
8
+
size: xs
9
+
---
10
+
11
+
`createUseFetch` creates a custom [`useFetch`](/docs/4.x/api/composables/use-fetch) composable with pre-defined options. The resulting composable is fully typed and works exactly like `useFetch`, but with your defaults baked in.
12
+
13
+
::note
14
+
`createUseFetch` is a compiler macro. It must be used as an **exported** declaration in the `composables/` directory (or any directory scanned by the Nuxt compiler). Nuxt automatically injects de-duplication keys at build time.
The resulting `useAPI` composable has the same signature and return type as [`useFetch`](/docs/4.x/api/composables/use-fetch), with all options available for the caller to use or override.
When you pass a function, the factory options **override** the caller's options. The function receives the caller's options as its argument, so you can read them to compute your overrides:
75
+
76
+
```ts [app/composables/useAPI.ts]
77
+
// baseURL is always enforced, regardless of what the caller passes
If you're using a custom `useAsyncData`wrapper, do not await it in the composable as that can cause unexpected behavior. See recipe for custom async data fetcher.
Need a custom `useAsyncData`with pre-defined defaults? Use `createUseAsyncData` to create a fully typed custom composable. See the [custom useFetch recipe](/docs/4.x/guide/recipes/custom-usefetch) for details.
If you're using a custom `useFetch`wrapper, do not await it in the composable as that can cause unexpected behavior. See recipe for custom async data fetcher.
Need a custom `useFetch`with pre-defined defaults (like `baseURL` or auth headers)? Use `createUseFetch` to create a fully typed custom composable.
30
30
::
31
31
32
32
::note
@@ -87,7 +87,7 @@ Keyed state created using `useFetch` can be retrieved across your Nuxt applicati
87
87
::
88
88
89
89
::warning
90
-
`useFetch` is a reserved function name transformed by the compiler, so you should not name your own function `useFetch`.
90
+
`useFetch` is a reserved function name transformed by the compiler, so you should not name your own function `useFetch`. To create a custom variant with pre-defined options, use [`createUseFetch`](/docs/4.x/guide/recipes/custom-usefetch#custom-usefetch-with-createusefetch) instead.
91
91
::
92
92
93
93
::warning
@@ -151,7 +151,6 @@ type UseFetchOptions<DataT> = {
0 commit comments