@nuxt/docs 4.1.2 → 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/1.getting-started/01.introduction.md +6 -6
- package/1.getting-started/02.installation.md +2 -1
- package/1.getting-started/03.configuration.md +36 -36
- package/1.getting-started/04.views.md +9 -9
- package/1.getting-started/05.assets.md +15 -9
- package/1.getting-started/06.styling.md +58 -48
- package/1.getting-started/07.routing.md +17 -17
- package/1.getting-started/08.seo-meta.md +59 -46
- package/1.getting-started/09.transitions.md +49 -44
- package/1.getting-started/10.data-fetching.md +104 -81
- package/1.getting-started/11.state-management.md +26 -19
- package/1.getting-started/12.error-handling.md +22 -20
- package/1.getting-started/13.server.md +8 -8
- package/1.getting-started/14.layers.md +22 -16
- package/1.getting-started/15.prerendering.md +32 -32
- package/1.getting-started/16.deployment.md +10 -10
- package/1.getting-started/17.testing.md +44 -44
- package/1.getting-started/18.upgrade.md +53 -71
- package/2.guide/0.index.md +7 -7
- package/2.guide/{2.directory-structure → 1.directory-structure}/.navigation.yml +1 -1
- package/2.guide/{2.directory-structure → 1.directory-structure}/0.nuxt.md +3 -3
- package/2.guide/1.directory-structure/0.output.md +18 -0
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/.navigation.yml +1 -1
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.assets.md +4 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.components.md +45 -28
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.composables.md +13 -13
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.layouts.md +19 -15
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.middleware.md +31 -25
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.pages.md +39 -37
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.plugins.md +25 -25
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.utils.md +7 -7
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/3.app-config.md +18 -18
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/3.app.md +7 -7
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/3.error.md +6 -6
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.content.md +7 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.modules.md +8 -8
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.node_modules.md +2 -2
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.public.md +2 -2
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.server.md +35 -35
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.shared.md +7 -7
- package/2.guide/{2.directory-structure → 1.directory-structure}/2.env.md +8 -8
- package/2.guide/{2.directory-structure → 1.directory-structure}/2.gitignore.md +1 -1
- package/2.guide/{2.directory-structure → 1.directory-structure}/2.nuxtignore.md +5 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/2.nuxtrc.md +4 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.nuxt-config.md +3 -3
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.package.md +1 -1
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.tsconfig.md +3 -3
- package/2.guide/{1.concepts → 2.concepts}/1.auto-imports.md +22 -22
- package/2.guide/{1.concepts → 2.concepts}/10.nuxt-lifecycle.md +17 -17
- package/2.guide/{1.concepts → 2.concepts}/2.vuejs-development.md +13 -13
- package/2.guide/{1.concepts → 2.concepts}/3.rendering.md +24 -22
- package/2.guide/{1.concepts → 2.concepts}/4.server-engine.md +6 -6
- package/2.guide/{1.concepts → 2.concepts}/5.modules.md +5 -5
- package/2.guide/{1.concepts → 2.concepts}/7.esm.md +17 -15
- package/2.guide/{1.concepts → 2.concepts}/8.typescript.md +12 -12
- package/2.guide/3.going-further/1.events.md +3 -3
- package/2.guide/3.going-further/1.experimental-features.md +246 -85
- package/2.guide/3.going-further/1.features.md +44 -9
- package/2.guide/3.going-further/1.internals.md +25 -25
- package/2.guide/3.going-further/10.runtime-config.md +12 -12
- package/2.guide/3.going-further/11.nightly-release-channel.md +1 -1
- package/2.guide/3.going-further/2.hooks.md +14 -14
- package/2.guide/3.going-further/3.modules.md +96 -94
- package/2.guide/3.going-further/4.kit.md +7 -7
- package/2.guide/3.going-further/6.nuxt-app.md +8 -8
- package/2.guide/3.going-further/7.layers.md +62 -53
- package/2.guide/3.going-further/9.debugging.md +2 -2
- package/2.guide/4.recipes/1.custom-routing.md +30 -30
- package/2.guide/4.recipes/2.vite-plugin.md +4 -4
- package/2.guide/4.recipes/3.custom-usefetch.md +13 -13
- package/2.guide/4.recipes/4.sessions-and-authentication.md +35 -21
- package/2.guide/5.best-practices/hydration.md +4 -4
- package/2.guide/5.best-practices/performance.md +17 -17
- package/3.api/1.components/1.client-only.md +6 -3
- package/3.api/1.components/1.nuxt-client-fallback.md +10 -7
- package/3.api/1.components/10.nuxt-picture.md +1 -1
- package/3.api/1.components/11.teleports.md +5 -2
- package/3.api/1.components/12.nuxt-route-announcer.md +9 -9
- package/3.api/1.components/13.nuxt-time.md +44 -17
- package/3.api/1.components/2.nuxt-page.md +6 -6
- package/3.api/1.components/3.nuxt-layout.md +15 -10
- package/3.api/1.components/4.nuxt-link.md +42 -22
- package/3.api/1.components/5.nuxt-loading-indicator.md +3 -3
- package/3.api/1.components/6.nuxt-error-boundary.md +12 -10
- package/3.api/2.composables/on-prehydrate.md +2 -2
- package/3.api/2.composables/use-app-config.md +1 -1
- package/3.api/2.composables/use-async-data.md +20 -20
- package/3.api/2.composables/use-cookie.md +29 -21
- package/3.api/2.composables/use-error.md +2 -2
- package/3.api/2.composables/use-fetch.md +58 -32
- package/3.api/2.composables/use-head-safe.md +7 -7
- package/3.api/2.composables/use-head.md +5 -5
- package/3.api/2.composables/use-hydration.md +6 -6
- package/3.api/2.composables/use-lazy-async-data.md +4 -4
- package/3.api/2.composables/use-lazy-fetch.md +4 -4
- package/3.api/2.composables/use-loading-indicator.md +12 -12
- package/3.api/2.composables/use-nuxt-app.md +22 -22
- package/3.api/2.composables/use-nuxt-data.md +8 -8
- package/3.api/2.composables/use-preview-mode.md +15 -18
- package/3.api/2.composables/use-request-event.md +1 -1
- package/3.api/2.composables/use-request-fetch.md +3 -3
- package/3.api/2.composables/use-request-header.md +1 -1
- package/3.api/2.composables/use-request-headers.md +4 -4
- package/3.api/2.composables/use-request-url.md +1 -1
- package/3.api/2.composables/use-response-header.md +9 -10
- package/3.api/2.composables/use-route-announcer.md +4 -4
- package/3.api/2.composables/use-route.md +1 -1
- package/3.api/2.composables/use-router.md +10 -8
- package/3.api/2.composables/use-runtime-config.md +11 -11
- package/3.api/2.composables/use-runtime-hook.md +2 -2
- package/3.api/2.composables/use-seo-meta.md +4 -4
- package/3.api/2.composables/use-server-seo-meta.md +6 -6
- package/3.api/2.composables/use-state.md +5 -5
- package/3.api/3.utils/$fetch.md +10 -8
- package/3.api/3.utils/abort-navigation.md +3 -3
- package/3.api/3.utils/add-route-middleware.md +5 -5
- package/3.api/3.utils/call-once.md +6 -6
- package/3.api/3.utils/clear-error.md +3 -3
- package/3.api/3.utils/clear-nuxt-data.md +3 -3
- package/3.api/3.utils/clear-nuxt-state.md +3 -3
- package/3.api/3.utils/create-error.md +2 -2
- package/3.api/3.utils/define-lazy-hydration-component.md +13 -13
- package/3.api/3.utils/define-nuxt-component.md +5 -5
- package/3.api/3.utils/define-nuxt-plugin.md +13 -13
- package/3.api/3.utils/define-nuxt-route-middleware.md +5 -5
- package/3.api/3.utils/define-page-meta.md +23 -23
- package/3.api/3.utils/define-route-rules.md +7 -7
- package/3.api/3.utils/navigate-to.md +11 -11
- package/3.api/3.utils/prefetch-components.md +1 -1
- package/3.api/3.utils/preload-components.md +1 -1
- package/3.api/3.utils/preload-route-components.md +2 -2
- package/3.api/3.utils/prerender-routes.md +3 -3
- package/3.api/3.utils/refresh-cookie.md +4 -4
- package/3.api/3.utils/refresh-nuxt-data.md +12 -7
- package/3.api/3.utils/reload-nuxt-app.md +3 -3
- package/3.api/3.utils/set-page-layout.md +1 -1
- package/3.api/3.utils/set-response-status.md +3 -3
- package/3.api/3.utils/show-error.md +5 -5
- package/3.api/3.utils/update-app-config.md +4 -3
- package/3.api/4.commands/add.md +1 -1
- package/3.api/4.commands/analyze.md +2 -1
- package/3.api/4.commands/build.md +2 -1
- package/3.api/4.commands/dev.md +5 -4
- package/3.api/4.commands/generate.md +3 -2
- package/3.api/4.commands/init.md +3 -2
- package/3.api/4.commands/module.md +4 -4
- package/3.api/4.commands/prepare.md +7 -2
- package/3.api/4.commands/preview.md +5 -4
- package/3.api/4.commands/test.md +40 -0
- package/3.api/4.commands/typecheck.md +5 -3
- package/3.api/4.commands/upgrade.md +3 -3
- package/3.api/5.kit/1.modules.md +36 -36
- package/3.api/5.kit/10.runtime-config.md +1 -1
- package/3.api/5.kit/10.templates.md +8 -6
- package/3.api/5.kit/11.nitro.md +62 -62
- package/3.api/5.kit/12.resolving.md +2 -2
- package/3.api/5.kit/14.builder.md +1 -0
- package/3.api/5.kit/15.examples.md +2 -2
- package/3.api/5.kit/16.layers.md +26 -26
- package/3.api/5.kit/3.compatibility.md +14 -14
- package/3.api/5.kit/4.autoimports.md +13 -13
- package/3.api/5.kit/5.components.md +7 -7
- package/3.api/5.kit/6.context.md +3 -3
- package/3.api/5.kit/7.pages.md +7 -7
- package/3.api/5.kit/8.layout.md +2 -2
- package/3.api/5.kit/9.plugins.md +5 -4
- package/3.api/6.advanced/1.hooks.md +3 -3
- package/3.api/6.advanced/2.import-meta.md +3 -3
- package/3.api/6.nuxt-config.md +300 -865
- package/3.api/index.md +7 -7
- package/5.community/2.getting-help.md +1 -1
- package/5.community/3.reporting-bugs.md +1 -1
- package/5.community/4.contribution.md +11 -11
- package/5.community/5.framework-contribution.md +4 -4
- package/5.community/6.roadmap.md +1 -1
- package/6.bridge/1.overview.md +13 -13
- package/6.bridge/10.configuration.md +2 -1
- package/6.bridge/2.typescript.md +3 -3
- package/6.bridge/3.bridge-composition-api.md +8 -8
- package/6.bridge/4.plugins-and-middleware.md +9 -9
- package/6.bridge/5.nuxt3-compatible-api.md +20 -17
- package/6.bridge/6.meta.md +20 -19
- package/6.bridge/7.runtime-config.md +1 -1
- package/6.bridge/8.nitro.md +3 -3
- package/6.bridge/9.vite.md +4 -4
- package/7.migration/1.overview.md +2 -2
- package/7.migration/10.bundling.md +1 -1
- package/7.migration/11.server.md +3 -3
- package/7.migration/2.configuration.md +23 -21
- package/7.migration/20.module-authors.md +7 -7
- package/7.migration/3.auto-imports.md +3 -3
- package/7.migration/4.meta.md +21 -18
- package/7.migration/5.plugins-and-middleware.md +8 -8
- package/7.migration/6.pages-and-layouts.md +28 -24
- package/7.migration/7.component-options.md +18 -18
- package/7.migration/8.runtime-config.md +7 -7
- package/package.json +1 -1
- package/2.guide/2.directory-structure/0.output.md +0 -18
- /package/2.guide/{1.concepts → 2.concepts}/.navigation.yml +0 -0
- /package/2.guide/{1.concepts → 2.concepts}/9.code-style.md +0 -0
|
@@ -4,23 +4,23 @@ description: Nuxt provides composables to handle data fetching within your appli
|
|
|
4
4
|
navigation.icon: i-lucide-cable
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/api/composables/use-async-data) and `$fetch`.
|
|
7
|
+
Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/4.x/api/composables/use-async-data) and `$fetch`.
|
|
8
8
|
|
|
9
9
|
In a nutshell:
|
|
10
10
|
|
|
11
|
-
- [`$fetch`](/docs/api/utils/dollarfetch) is the simplest way to make a network request.
|
|
12
|
-
- [`useFetch`](/docs/api/composables/use-fetch) is a wrapper around `$fetch` that fetches data only once in [universal rendering](/docs/guide/concepts/rendering#universal-rendering).
|
|
13
|
-
- [`useAsyncData`](/docs/api/composables/use-async-data) is similar to `useFetch` but offers more fine-grained control.
|
|
11
|
+
- [`$fetch`](/docs/4.x/api/utils/dollarfetch) is the simplest way to make a network request.
|
|
12
|
+
- [`useFetch`](/docs/4.x/api/composables/use-fetch) is a wrapper around `$fetch` that fetches data only once in [universal rendering](/docs/4.x/guide/concepts/rendering#universal-rendering).
|
|
13
|
+
- [`useAsyncData`](/docs/4.x/api/composables/use-async-data) is similar to `useFetch` but offers more fine-grained control.
|
|
14
14
|
|
|
15
15
|
Both `useFetch` and `useAsyncData` share a common set of options and patterns that we will detail in the last sections.
|
|
16
16
|
|
|
17
17
|
## The need for `useFetch` and `useAsyncData`
|
|
18
18
|
|
|
19
|
-
Nuxt is a framework which can run isomorphic (or universal) code in both server and client environments. If the [`$fetch` function](/docs/api/utils/dollarfetch) is used to perform data fetching in the setup function of a Vue component, this may cause data to be fetched twice, once on the server (to render the HTML) and once again on the client (when the HTML is hydrated). This can cause hydration issues, increase the time to interactivity and cause unpredictable behavior.
|
|
19
|
+
Nuxt is a framework which can run isomorphic (or universal) code in both server and client environments. If the [`$fetch` function](/docs/4.x/api/utils/dollarfetch) is used to perform data fetching in the setup function of a Vue component, this may cause data to be fetched twice, once on the server (to render the HTML) and once again on the client (when the HTML is hydrated). This can cause hydration issues, increase the time to interactivity and cause unpredictable behavior.
|
|
20
20
|
|
|
21
|
-
The [`useFetch`](/docs/api/composables/use-fetch) and [`useAsyncData`](/docs/api/composables/use-async-data) composables solve this problem by ensuring that if an API call is made on the server, the data is forwarded to the client in the payload.
|
|
21
|
+
The [`useFetch`](/docs/4.x/api/composables/use-fetch) and [`useAsyncData`](/docs/4.x/api/composables/use-async-data) composables solve this problem by ensuring that if an API call is made on the server, the data is forwarded to the client in the payload.
|
|
22
22
|
|
|
23
|
-
The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser [during hydration](/docs/guide/concepts/rendering#universal-rendering).
|
|
23
|
+
The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/4.x/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser [during hydration](/docs/4.x/guide/concepts/rendering#universal-rendering).
|
|
24
24
|
|
|
25
25
|
::tip
|
|
26
26
|
Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the **Payload tab**.
|
|
@@ -30,12 +30,12 @@ Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the *
|
|
|
30
30
|
<script setup lang="ts">
|
|
31
31
|
const { data } = await useFetch('/api/data')
|
|
32
32
|
|
|
33
|
-
async function handleFormSubmit() {
|
|
33
|
+
async function handleFormSubmit () {
|
|
34
34
|
const res = await $fetch('/api/submit', {
|
|
35
35
|
method: 'POST',
|
|
36
36
|
body: {
|
|
37
37
|
// My form data
|
|
38
|
-
}
|
|
38
|
+
},
|
|
39
39
|
})
|
|
40
40
|
}
|
|
41
41
|
</script>
|
|
@@ -59,7 +59,7 @@ In the example above, `useFetch` would make sure that the request would occur in
|
|
|
59
59
|
Nuxt uses Vue's [`<Suspense>`](https://vuejs.org/guide/built-ins/suspense) component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-call basis.
|
|
60
60
|
|
|
61
61
|
::note
|
|
62
|
-
You can add the [`<NuxtLoadingIndicator>`](/docs/api/components/nuxt-loading-indicator) to add a progress bar between page navigations.
|
|
62
|
+
You can add the [`<NuxtLoadingIndicator>`](/docs/4.x/api/components/nuxt-loading-indicator) to add a progress bar between page navigations.
|
|
63
63
|
::
|
|
64
64
|
|
|
65
65
|
## `$fetch`
|
|
@@ -68,33 +68,33 @@ Nuxt includes the [ofetch](https://github.com/unjs/ofetch) library, and is auto-
|
|
|
68
68
|
|
|
69
69
|
```vue twoslash [pages/todos.vue]
|
|
70
70
|
<script setup lang="ts">
|
|
71
|
-
async function addTodo() {
|
|
71
|
+
async function addTodo () {
|
|
72
72
|
const todo = await $fetch('/api/todos', {
|
|
73
73
|
method: 'POST',
|
|
74
74
|
body: {
|
|
75
75
|
// My todo data
|
|
76
|
-
}
|
|
76
|
+
},
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
</script>
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
::warning
|
|
83
|
-
Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](#the-need-for-usefetch-and-useasyncdata). :br
|
|
84
|
-
It is recommended to use `$fetch` for client-side interactions (event-based) or combined with [`useAsyncData`](#useasyncdata) when fetching the initial component data.
|
|
83
|
+
Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](/docs/4.x/getting-started/data-fetching#the-need-for-usefetch-and-useasyncdata). :br
|
|
84
|
+
It is recommended to use `$fetch` for client-side interactions (event-based) or combined with [`useAsyncData`](/docs/4.x/getting-started/data-fetching#useasyncdata) when fetching the initial component data.
|
|
85
85
|
::
|
|
86
86
|
|
|
87
|
-
::read-more{to="/docs/api/utils/dollarfetch"}
|
|
87
|
+
::read-more{to="/docs/4.x/api/utils/dollarfetch"}
|
|
88
88
|
Read more about `$fetch`.
|
|
89
89
|
::
|
|
90
90
|
|
|
91
91
|
### Pass Client Headers to the API
|
|
92
92
|
|
|
93
|
-
When calling `useFetch` on the server, Nuxt will use [`useRequestFetch`](/docs/api/composables/use-request-fetch) to proxy client headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
|
|
93
|
+
When calling `useFetch` on the server, Nuxt will use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy client headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
|
|
94
94
|
|
|
95
95
|
```vue
|
|
96
96
|
<script setup lang="ts">
|
|
97
|
-
const { data } = await useFetch('/api/echo')
|
|
97
|
+
const { data } = await useFetch('/api/echo')
|
|
98
98
|
</script>
|
|
99
99
|
```
|
|
100
100
|
|
|
@@ -103,20 +103,20 @@ const { data } = await useFetch('/api/echo');
|
|
|
103
103
|
export default defineEventHandler(event => parseCookies(event))
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
Alternatively, the example below shows how to use [`useRequestHeaders`](/docs/api/composables/use-request-headers) to access and send cookies to the API from a server-side request (originating on the client). Using an isomorphic `$fetch` call, we ensure that the API endpoint has access to the same `cookie` header originally sent by the user's browser. This is only necessary if you aren't using `useFetch`.
|
|
106
|
+
Alternatively, the example below shows how to use [`useRequestHeaders`](/docs/4.x/api/composables/use-request-headers) to access and send cookies to the API from a server-side request (originating on the client). Using an isomorphic `$fetch` call, we ensure that the API endpoint has access to the same `cookie` header originally sent by the user's browser. This is only necessary if you aren't using `useFetch`.
|
|
107
107
|
|
|
108
108
|
```vue
|
|
109
109
|
<script setup lang="ts">
|
|
110
110
|
const headers = useRequestHeaders(['cookie'])
|
|
111
111
|
|
|
112
|
-
async function getCurrentUser() {
|
|
112
|
+
async function getCurrentUser () {
|
|
113
113
|
return await $fetch('/api/me', { headers })
|
|
114
114
|
}
|
|
115
115
|
</script>
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
::tip
|
|
119
|
-
You can also use [`useRequestFetch`](/docs/api/composables/use-request-fetch) to proxy headers to the call automatically.
|
|
119
|
+
You can also use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy headers to the call automatically.
|
|
120
120
|
::
|
|
121
121
|
|
|
122
122
|
::caution
|
|
@@ -130,7 +130,7 @@ Be very careful before proxying headers to an external API and just include head
|
|
|
130
130
|
|
|
131
131
|
## `useFetch`
|
|
132
132
|
|
|
133
|
-
The [`useFetch`](/docs/api/composables/use-fetch) composable uses `$fetch` under-the-hood to make SSR-safe network calls in the setup function.
|
|
133
|
+
The [`useFetch`](/docs/4.x/api/composables/use-fetch) composable uses `$fetch` under-the-hood to make SSR-safe network calls in the setup function.
|
|
134
134
|
|
|
135
135
|
```vue twoslash [app/app.vue]
|
|
136
136
|
<script setup lang="ts">
|
|
@@ -142,13 +142,13 @@ const { data: count } = await useFetch('/api/count')
|
|
|
142
142
|
</template>
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
This composable is a wrapper around the [`useAsyncData`](/docs/api/composables/use-async-data) composable and `$fetch` utility.
|
|
145
|
+
This composable is a wrapper around the [`useAsyncData`](/docs/4.x/api/composables/use-async-data) composable and `$fetch` utility.
|
|
146
146
|
|
|
147
147
|
:video-accordion{title="Watch a video from Alexander Lichter to avoid using useFetch the wrong way" videoId="njsGVmcWviY"}
|
|
148
148
|
|
|
149
|
-
:read-more{to="/docs/api/composables/use-fetch"}
|
|
149
|
+
:read-more{to="/docs/4.x/api/composables/use-fetch"}
|
|
150
150
|
|
|
151
|
-
:link-example{to="/docs/examples/features/data-fetching"}
|
|
151
|
+
:link-example{to="/docs/4.x/examples/features/data-fetching"}
|
|
152
152
|
|
|
153
153
|
## `useAsyncData`
|
|
154
154
|
|
|
@@ -156,12 +156,12 @@ The `useAsyncData` composable is responsible for wrapping async logic and return
|
|
|
156
156
|
|
|
157
157
|
::tip
|
|
158
158
|
`useFetch(url)` is nearly equivalent to `useAsyncData(url, () => event.$fetch(url))`. :br
|
|
159
|
-
It's developer experience sugar for the most common use case. (You can find out more about `event.fetch` at [`useRequestFetch`](/docs/api/composables/use-request-fetch).)
|
|
159
|
+
It's developer experience sugar for the most common use case. (You can find out more about `event.fetch` at [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch).)
|
|
160
160
|
::
|
|
161
161
|
|
|
162
162
|
:video-accordion{title="Watch a video from Alexander Lichter to dig deeper into the difference between useFetch and useAsyncData" videoId="0X-aOpSGabA"}
|
|
163
163
|
|
|
164
|
-
There are some cases when using the [`useFetch`](/docs/api/composables/use-fetch) composable is not appropriate, for example when a CMS or a third-party provide their own query layer. In this case, you can use [`useAsyncData`](/docs/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable.
|
|
164
|
+
There are some cases when using the [`useFetch`](/docs/4.x/api/composables/use-fetch) composable is not appropriate, for example when a CMS or a third-party provide their own query layer. In this case, you can use [`useAsyncData`](/docs/4.x/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable.
|
|
165
165
|
|
|
166
166
|
```vue [app/pages/users.vue]
|
|
167
167
|
<script setup lang="ts">
|
|
@@ -173,11 +173,11 @@ const { data, error } = await useAsyncData(() => myGetFunction('users'))
|
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
::note
|
|
176
|
-
The first argument of [`useAsyncData`](/docs/api/composables/use-async-data) is a unique key used to cache the response of the second argument, the querying function. This key can be ignored by directly passing the querying function, the key will be auto-generated.
|
|
176
|
+
The first argument of [`useAsyncData`](/docs/4.x/api/composables/use-async-data) is a unique key used to cache the response of the second argument, the querying function. This key can be ignored by directly passing the querying function, the key will be auto-generated.
|
|
177
177
|
:br :br
|
|
178
178
|
Since the autogenerated key only takes into account the file and line where `useAsyncData` is invoked, it is recommended to always create your own key to avoid unwanted behavior, like when you are creating your own custom composable wrapping `useAsyncData`.
|
|
179
179
|
:br :br
|
|
180
|
-
Setting a key can be useful to share the same data between components using [`useNuxtData`](/docs/api/composables/use-nuxt-data) or to [refresh specific data](/docs/api/utils/refresh-nuxt-data#refresh-specific-data).
|
|
180
|
+
Setting a key can be useful to share the same data between components using [`useNuxtData`](/docs/4.x/api/composables/use-nuxt-data) or to [refresh specific data](/docs/4.x/api/utils/refresh-nuxt-data#refresh-specific-data).
|
|
181
181
|
::
|
|
182
182
|
|
|
183
183
|
```vue [app/pages/users/[id\\].vue]
|
|
@@ -197,7 +197,7 @@ The `useAsyncData` composable is a great way to wrap and wait for multiple `$fet
|
|
|
197
197
|
const { data: discounts, status } = await useAsyncData('cart-discount', async () => {
|
|
198
198
|
const [coupons, offers] = await Promise.all([
|
|
199
199
|
$fetch('/cart/coupons'),
|
|
200
|
-
$fetch('/cart/offers')
|
|
200
|
+
$fetch('/cart/offers'),
|
|
201
201
|
])
|
|
202
202
|
|
|
203
203
|
return { coupons, offers }
|
|
@@ -208,7 +208,7 @@ const { data: discounts, status } = await useAsyncData('cart-discount', async ()
|
|
|
208
208
|
```
|
|
209
209
|
|
|
210
210
|
::note
|
|
211
|
-
`useAsyncData` is for fetching and caching data, not triggering side effects like calling Pinia actions, as this can cause unintended behavior such as repeated executions with nullish values. If you need to trigger side effects, use the [`callOnce`](/docs/api/utils/call-once) utility to do so.
|
|
211
|
+
`useAsyncData` is for fetching and caching data, not triggering side effects like calling Pinia actions, as this can cause unintended behavior such as repeated executions with nullish values. If you need to trigger side effects, use the [`callOnce`](/docs/4.x/api/utils/call-once) utility to do so.
|
|
212
212
|
|
|
213
213
|
```vue
|
|
214
214
|
<script setup lang="ts">
|
|
@@ -220,7 +220,7 @@ await useAsyncData(() => offersStore.getOffer(route.params.slug))
|
|
|
220
220
|
```
|
|
221
221
|
::
|
|
222
222
|
|
|
223
|
-
::read-more{to="/docs/api/composables/use-async-data"}
|
|
223
|
+
::read-more{to="/docs/4.x/api/composables/use-async-data"}
|
|
224
224
|
Read more about `useAsyncData`.
|
|
225
225
|
::
|
|
226
226
|
|
|
@@ -246,7 +246,7 @@ If you have not fetched data on the server (for example, with `server: false`),
|
|
|
246
246
|
|
|
247
247
|
## Options
|
|
248
248
|
|
|
249
|
-
[`useAsyncData`](/docs/api/composables/use-async-data) and [`useFetch`](/docs/api/composables/use-fetch) return the same object type and accept a common set of options as their last argument. They can help you control the composables behavior, such as navigation blocking, caching or execution.
|
|
249
|
+
[`useAsyncData`](/docs/4.x/api/composables/use-async-data) and [`useFetch`](/docs/4.x/api/composables/use-fetch) return the same object type and accept a common set of options as their last argument. They can help you control the composables behavior, such as navigation blocking, caching or execution.
|
|
250
250
|
|
|
251
251
|
### Lazy
|
|
252
252
|
|
|
@@ -255,7 +255,7 @@ By default, data fetching composables will wait for the resolution of their asyn
|
|
|
255
255
|
```vue twoslash [app/app.vue]
|
|
256
256
|
<script setup lang="ts">
|
|
257
257
|
const { status, data: posts } = useFetch('/api/posts', {
|
|
258
|
-
lazy: true
|
|
258
|
+
lazy: true,
|
|
259
259
|
})
|
|
260
260
|
</script>
|
|
261
261
|
|
|
@@ -272,7 +272,7 @@ const { status, data: posts } = useFetch('/api/posts', {
|
|
|
272
272
|
</template>
|
|
273
273
|
```
|
|
274
274
|
|
|
275
|
-
You can alternatively use [`useLazyFetch`](/docs/api/composables/use-lazy-fetch) and `useLazyAsyncData` as convenient methods to perform the same.
|
|
275
|
+
You can alternatively use [`useLazyFetch`](/docs/4.x/api/composables/use-lazy-fetch) and `useLazyAsyncData` as convenient methods to perform the same.
|
|
276
276
|
|
|
277
277
|
```vue twoslash
|
|
278
278
|
<script setup lang="ts">
|
|
@@ -280,11 +280,11 @@ const { status, data: posts } = useLazyFetch('/api/posts')
|
|
|
280
280
|
</script>
|
|
281
281
|
```
|
|
282
282
|
|
|
283
|
-
::read-more{to="/docs/api/composables/use-lazy-fetch"}
|
|
283
|
+
::read-more{to="/docs/4.x/api/composables/use-lazy-fetch"}
|
|
284
284
|
Read more about `useLazyFetch`.
|
|
285
285
|
::
|
|
286
286
|
|
|
287
|
-
::read-more{to="/docs/api/composables/use-lazy-async-data"}
|
|
287
|
+
::read-more{to="/docs/4.x/api/composables/use-lazy-async-data"}
|
|
288
288
|
Read more about `useLazyAsyncData`.
|
|
289
289
|
::
|
|
290
290
|
|
|
@@ -303,11 +303,11 @@ const articles = await useFetch('/api/article')
|
|
|
303
303
|
/* This call will only be performed on the client */
|
|
304
304
|
const { status, data: comments } = useFetch('/api/comments', {
|
|
305
305
|
lazy: true,
|
|
306
|
-
server: false
|
|
306
|
+
server: false,
|
|
307
307
|
})
|
|
308
308
|
```
|
|
309
309
|
|
|
310
|
-
The `useFetch` composable is meant to be invoked in setup method or called directly at the top level of a function in lifecycle hooks, otherwise you should use [`$fetch` method](#fetch).
|
|
310
|
+
The `useFetch` composable is meant to be invoked in setup method or called directly at the top level of a function in lifecycle hooks, otherwise you should use [`$fetch` method](/docs/4.x/getting-started/data-fetching#fetch).
|
|
311
311
|
|
|
312
312
|
### Minimize payload size
|
|
313
313
|
|
|
@@ -317,7 +317,7 @@ The `pick` option helps you to minimize the payload size stored in your HTML doc
|
|
|
317
317
|
<script setup lang="ts">
|
|
318
318
|
/* only pick the fields used in your template */
|
|
319
319
|
const { data: mountain } = await useFetch('/api/mountains/everest', {
|
|
320
|
-
pick: ['title', 'description']
|
|
320
|
+
pick: ['title', 'description'],
|
|
321
321
|
})
|
|
322
322
|
</script>
|
|
323
323
|
|
|
@@ -333,7 +333,7 @@ If you need more control or map over several objects, you can use the `transform
|
|
|
333
333
|
const { data: mountains } = await useFetch('/api/mountains', {
|
|
334
334
|
transform: (mountains) => {
|
|
335
335
|
return mountains.map(mountain => ({ title: mountain.title, description: mountain.description }))
|
|
336
|
-
}
|
|
336
|
+
},
|
|
337
337
|
})
|
|
338
338
|
```
|
|
339
339
|
|
|
@@ -347,13 +347,13 @@ Both `pick` and `transform` don't prevent the unwanted data from being fetched i
|
|
|
347
347
|
|
|
348
348
|
#### Keys
|
|
349
349
|
|
|
350
|
-
[`useFetch`](/docs/api/composables/use-fetch) and [`useAsyncData`](/docs/api/composables/use-async-data) use keys to prevent refetching the same data.
|
|
350
|
+
[`useFetch`](/docs/4.x/api/composables/use-fetch) and [`useAsyncData`](/docs/4.x/api/composables/use-async-data) use keys to prevent refetching the same data.
|
|
351
351
|
|
|
352
|
-
- [`useFetch`](/docs/api/composables/use-fetch) uses the provided URL as a key. Alternatively, a `key` value can be provided in the `options` object passed as a last argument.
|
|
353
|
-
- [`useAsyncData`](/docs/api/composables/use-async-data) uses its first argument as a key if it is a string. If the first argument is the handler function that performs the query, then a key that is unique to the file name and line number of the instance of `useAsyncData` will be generated for you.
|
|
352
|
+
- [`useFetch`](/docs/4.x/api/composables/use-fetch) uses the provided URL as a key. Alternatively, a `key` value can be provided in the `options` object passed as a last argument.
|
|
353
|
+
- [`useAsyncData`](/docs/4.x/api/composables/use-async-data) uses its first argument as a key if it is a string. If the first argument is the handler function that performs the query, then a key that is unique to the file name and line number of the instance of `useAsyncData` will be generated for you.
|
|
354
354
|
|
|
355
355
|
::tip
|
|
356
|
-
To get the cached data by key, you can use [`useNuxtData`](/docs/api/composables/use-nuxt-data)
|
|
356
|
+
To get the cached data by key, you can use [`useNuxtData`](/docs/4.x/api/composables/use-nuxt-data)
|
|
357
357
|
::
|
|
358
358
|
|
|
359
359
|
:video-accordion{title="Watch a video from Vue School on caching data with the key option" videoId="1026410044" platform="vimeo"}
|
|
@@ -406,7 +406,7 @@ You can use computed refs, plain refs or getter functions as keys, allowing for
|
|
|
406
406
|
const userId = ref('123')
|
|
407
407
|
const { data: user } = useAsyncData(
|
|
408
408
|
computed(() => `user-${userId.value}`),
|
|
409
|
-
() => fetchUser(userId.value)
|
|
409
|
+
() => fetchUser(userId.value),
|
|
410
410
|
)
|
|
411
411
|
|
|
412
412
|
// When userId changes, the data will be automatically refetched
|
|
@@ -426,15 +426,17 @@ const { data, error, execute, refresh } = await useFetch('/api/users')
|
|
|
426
426
|
<template>
|
|
427
427
|
<div>
|
|
428
428
|
<p>{{ data }}</p>
|
|
429
|
-
<button @click="() => refresh()">
|
|
429
|
+
<button @click="() => refresh()">
|
|
430
|
+
Refresh data
|
|
431
|
+
</button>
|
|
430
432
|
</div>
|
|
431
433
|
</template>
|
|
432
434
|
```
|
|
433
435
|
|
|
434
|
-
The `execute` function is an alias for `refresh` that works in exactly the same way but is more semantic for cases when the fetch is [not immediate](#not-immediate).
|
|
436
|
+
The `execute` function is an alias for `refresh` that works in exactly the same way but is more semantic for cases when the fetch is [not immediate](/docs/4.x/getting-started/data-fetching#not-immediate).
|
|
435
437
|
|
|
436
438
|
::tip
|
|
437
|
-
To globally refetch or invalidate cached data, see [`clearNuxtData`](/docs/api/utils/clear-nuxt-data) and [`refreshNuxtData`](/docs/api/utils/refresh-nuxt-data).
|
|
439
|
+
To globally refetch or invalidate cached data, see [`clearNuxtData`](/docs/4.x/api/utils/clear-nuxt-data) and [`refreshNuxtData`](/docs/4.x/api/utils/refresh-nuxt-data).
|
|
438
440
|
::
|
|
439
441
|
|
|
440
442
|
#### Clear
|
|
@@ -447,7 +449,9 @@ const { data, clear } = await useFetch('/api/users')
|
|
|
447
449
|
|
|
448
450
|
const route = useRoute()
|
|
449
451
|
watch(() => route.path, (path) => {
|
|
450
|
-
if (path === '/')
|
|
452
|
+
if (path === '/') {
|
|
453
|
+
clear()
|
|
454
|
+
}
|
|
451
455
|
})
|
|
452
456
|
</script>
|
|
453
457
|
```
|
|
@@ -462,7 +466,7 @@ const id = ref(1)
|
|
|
462
466
|
|
|
463
467
|
const { data, error, refresh } = await useFetch('/api/users', {
|
|
464
468
|
/* Changing the id will trigger a refetch */
|
|
465
|
-
watch: [id]
|
|
469
|
+
watch: [id],
|
|
466
470
|
})
|
|
467
471
|
</script>
|
|
468
472
|
```
|
|
@@ -474,12 +478,27 @@ Note that **watching a reactive value won't change the URL fetched**. For exampl
|
|
|
474
478
|
const id = ref(1)
|
|
475
479
|
|
|
476
480
|
const { data, error, refresh } = await useFetch(`/api/users/${id.value}`, {
|
|
477
|
-
watch: [id]
|
|
481
|
+
watch: [id],
|
|
478
482
|
})
|
|
479
483
|
</script>
|
|
480
484
|
```
|
|
481
485
|
|
|
482
|
-
If you need to change the URL based on a reactive value, you may want to use a [computed URL](#computed-url) instead.
|
|
486
|
+
If you need to change the URL based on a reactive value, you may want to use a [computed URL](/docs/4.x/getting-started/data-fetching#computed-url) instead.
|
|
487
|
+
|
|
488
|
+
When reactive fetch options are provided, they'll be automatically watched and trigger refetches. In some cases, it can be useful to opt-out of this behavior by specifying `watch: false`.
|
|
489
|
+
|
|
490
|
+
```ts
|
|
491
|
+
const id = ref(1)
|
|
492
|
+
|
|
493
|
+
// Won't automatically refetch when id changes
|
|
494
|
+
const { data, execute } = await useFetch('/api/users', {
|
|
495
|
+
query: { id }, // id is watched by default
|
|
496
|
+
watch: false, // disables automatic watching of id
|
|
497
|
+
})
|
|
498
|
+
|
|
499
|
+
// doesn't trigger refetch
|
|
500
|
+
id.value = 2
|
|
501
|
+
```
|
|
483
502
|
|
|
484
503
|
#### Computed URL
|
|
485
504
|
|
|
@@ -491,31 +510,35 @@ const id = ref(null)
|
|
|
491
510
|
|
|
492
511
|
const { data, status } = useLazyFetch('/api/user', {
|
|
493
512
|
query: {
|
|
494
|
-
user_id: id
|
|
495
|
-
}
|
|
513
|
+
user_id: id,
|
|
514
|
+
},
|
|
496
515
|
})
|
|
497
516
|
</script>
|
|
498
517
|
```
|
|
499
518
|
|
|
500
519
|
In the case of more complex URL construction, you may use a callback as a [computed getter](https://vuejs.org/guide/essentials/computed.html) that returns the URL string.
|
|
501
520
|
|
|
502
|
-
Every time a dependency changes, the data will be fetched using the newly constructed URL. Combine this with [not-immediate](#not-immediate), and you can wait until the reactive element changes before fetching.
|
|
521
|
+
Every time a dependency changes, the data will be fetched using the newly constructed URL. Combine this with [not-immediate](/docs/4.x/getting-started/data-fetching#not-immediate), and you can wait until the reactive element changes before fetching.
|
|
503
522
|
|
|
504
523
|
```vue
|
|
505
524
|
<script setup lang="ts">
|
|
506
525
|
const id = ref(null)
|
|
507
526
|
|
|
508
527
|
const { data, status } = useLazyFetch(() => `/api/users/${id.value}`, {
|
|
509
|
-
immediate: false
|
|
528
|
+
immediate: false,
|
|
510
529
|
})
|
|
511
530
|
|
|
512
|
-
const pending = computed(() => status.value === 'pending')
|
|
531
|
+
const pending = computed(() => status.value === 'pending')
|
|
513
532
|
</script>
|
|
514
533
|
|
|
515
534
|
<template>
|
|
516
535
|
<div>
|
|
517
536
|
<!-- disable the input while fetching -->
|
|
518
|
-
<input
|
|
537
|
+
<input
|
|
538
|
+
v-model="id"
|
|
539
|
+
type="number"
|
|
540
|
+
:disabled="pending"
|
|
541
|
+
>
|
|
519
542
|
|
|
520
543
|
<div v-if="status === 'idle'">
|
|
521
544
|
Type an user ID
|
|
@@ -532,7 +555,7 @@ const pending = computed(() => status.value === 'pending');
|
|
|
532
555
|
</template>
|
|
533
556
|
```
|
|
534
557
|
|
|
535
|
-
If you need to force a refresh when other reactive values change, you can also [watch other values](#watch).
|
|
558
|
+
If you need to force a refresh when other reactive values change, you can also [watch other values](/docs/4.x/getting-started/data-fetching#watch).
|
|
536
559
|
|
|
537
560
|
### Not immediate
|
|
538
561
|
|
|
@@ -543,13 +566,15 @@ With that, you will need both the `status` to handle the fetch lifecycle, and `e
|
|
|
543
566
|
```vue
|
|
544
567
|
<script setup lang="ts">
|
|
545
568
|
const { data, error, execute, status } = await useLazyFetch('/api/comments', {
|
|
546
|
-
immediate: false
|
|
569
|
+
immediate: false,
|
|
547
570
|
})
|
|
548
571
|
</script>
|
|
549
572
|
|
|
550
573
|
<template>
|
|
551
574
|
<div v-if="status === 'idle'">
|
|
552
|
-
<button @click="execute">
|
|
575
|
+
<button @click="execute">
|
|
576
|
+
Get data
|
|
577
|
+
</button>
|
|
553
578
|
</div>
|
|
554
579
|
|
|
555
580
|
<div v-else-if="status === 'pending'">
|
|
@@ -575,7 +600,7 @@ When we call `$fetch` in the browser, user headers like `cookie` will be directl
|
|
|
575
600
|
|
|
576
601
|
Normally, during server-side-rendering, due to security considerations, the `$fetch` wouldn't include the user's browser cookies, nor pass on cookies from the fetch response.
|
|
577
602
|
|
|
578
|
-
However, when calling `useFetch` with a relative URL on the server, Nuxt will use [`useRequestFetch`](/docs/api/composables/use-request-fetch) to proxy headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
|
|
603
|
+
However, when calling `useFetch` with a relative URL on the server, Nuxt will use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
|
|
579
604
|
|
|
580
605
|
### Pass Cookies From Server-side API Calls on SSR Response
|
|
581
606
|
|
|
@@ -621,9 +646,9 @@ export default defineNuxtComponent({
|
|
|
621
646
|
fetchKey: 'hello',
|
|
622
647
|
async asyncData () {
|
|
623
648
|
return {
|
|
624
|
-
hello: await $fetch('/api/hello')
|
|
649
|
+
hello: await $fetch('/api/hello'),
|
|
625
650
|
}
|
|
626
|
-
}
|
|
651
|
+
},
|
|
627
652
|
})
|
|
628
653
|
</script>
|
|
629
654
|
```
|
|
@@ -632,13 +657,13 @@ export default defineNuxtComponent({
|
|
|
632
657
|
Using `<script setup>` or `<script setup lang="ts">` are the recommended way of declaring Vue components in Nuxt.
|
|
633
658
|
::
|
|
634
659
|
|
|
635
|
-
:read-more{to="/docs/api/utils/define-nuxt-component"}
|
|
660
|
+
:read-more{to="/docs/4.x/api/utils/define-nuxt-component"}
|
|
636
661
|
|
|
637
662
|
## Serializing Data From Server to Client
|
|
638
663
|
|
|
639
|
-
When using `useAsyncData` and `useLazyAsyncData` to transfer data fetched on server to the client (as well as anything else that utilizes [the Nuxt payload](/docs/api/composables/use-nuxt-app#payload)), the payload is serialized with [`devalue`](https://github.com/Rich-Harris/devalue). This allows us to transfer not just basic JSON but also to serialize and revive/deserialize more advanced kinds of data, such as regular expressions, Dates, Map and Set, `ref`, `reactive`, `shallowRef`, `shallowReactive` and `NuxtError` - and more.
|
|
664
|
+
When using `useAsyncData` and `useLazyAsyncData` to transfer data fetched on server to the client (as well as anything else that utilizes [the Nuxt payload](/docs/4.x/api/composables/use-nuxt-app#payload)), the payload is serialized with [`devalue`](https://github.com/Rich-Harris/devalue). This allows us to transfer not just basic JSON but also to serialize and revive/deserialize more advanced kinds of data, such as regular expressions, Dates, Map and Set, `ref`, `reactive`, `shallowRef`, `shallowReactive` and `NuxtError` - and more.
|
|
640
665
|
|
|
641
|
-
It is also possible to define your own serializer/deserializer for types that are not supported by Nuxt. You can read more in the [`useNuxtApp`](/docs/api/composables/use-nuxt-app#payload) docs.
|
|
666
|
+
It is also possible to define your own serializer/deserializer for types that are not supported by Nuxt. You can read more in the [`useNuxtApp`](/docs/4.x/api/composables/use-nuxt-app#payload) docs.
|
|
642
667
|
|
|
643
668
|
::note
|
|
644
669
|
Note that this _does not apply_ to data passed from your server routes when fetched with `$fetch` or `useFetch` - see the next section for more information.
|
|
@@ -646,7 +671,7 @@ Note that this _does not apply_ to data passed from your server routes when fetc
|
|
|
646
671
|
|
|
647
672
|
## Serializing Data From API Routes
|
|
648
673
|
|
|
649
|
-
When fetching data from the `server` directory, the response is serialized using `JSON.stringify`. However, since serialization is limited to only JavaScript primitive types, Nuxt does its best to convert the return type of `$fetch` and [`useFetch`](/docs/api/composables/use-fetch) to match the actual value.
|
|
674
|
+
When fetching data from the `server` directory, the response is serialized using `JSON.stringify`. However, since serialization is limited to only JavaScript primitive types, Nuxt does its best to convert the return type of `$fetch` and [`useFetch`](/docs/4.x/api/composables/use-fetch) to match the actual value.
|
|
650
675
|
|
|
651
676
|
::read-more{icon="i-simple-icons-mdnwebdocs" to="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description" target="_blank"}
|
|
652
677
|
Learn more about `JSON.stringify` limitations.
|
|
@@ -676,7 +701,7 @@ export default defineEventHandler(() => {
|
|
|
676
701
|
const data = {
|
|
677
702
|
createdAt: new Date(),
|
|
678
703
|
|
|
679
|
-
toJSON() {
|
|
704
|
+
toJSON () {
|
|
680
705
|
return {
|
|
681
706
|
createdAt: {
|
|
682
707
|
year: this.createdAt.getFullYear(),
|
|
@@ -688,7 +713,6 @@ export default defineEventHandler(() => {
|
|
|
688
713
|
}
|
|
689
714
|
return data
|
|
690
715
|
})
|
|
691
|
-
|
|
692
716
|
```
|
|
693
717
|
|
|
694
718
|
```vue [app/app.vue]
|
|
@@ -719,9 +743,9 @@ export default defineEventHandler(() => {
|
|
|
719
743
|
createdAt: new Date(),
|
|
720
744
|
|
|
721
745
|
// Workaround the type conversion
|
|
722
|
-
toJSON() {
|
|
746
|
+
toJSON () {
|
|
723
747
|
return this
|
|
724
|
-
}
|
|
748
|
+
},
|
|
725
749
|
}
|
|
726
750
|
|
|
727
751
|
// Serialize the output to string, using superjson
|
|
@@ -757,7 +781,7 @@ When consuming SSE via POST request, you need to handle the connection manually.
|
|
|
757
781
|
const response = await $fetch<ReadableStream>('/chats/ask-ai', {
|
|
758
782
|
method: 'POST',
|
|
759
783
|
body: {
|
|
760
|
-
query:
|
|
784
|
+
query: 'Hello AI, how are you?',
|
|
761
785
|
},
|
|
762
786
|
responseType: 'stream',
|
|
763
787
|
})
|
|
@@ -769,8 +793,7 @@ const reader = response.pipeThrough(new TextDecoderStream()).getReader()
|
|
|
769
793
|
while (true) {
|
|
770
794
|
const { value, done } = await reader.read()
|
|
771
795
|
|
|
772
|
-
if (done)
|
|
773
|
-
break
|
|
796
|
+
if (done) { break }
|
|
774
797
|
|
|
775
798
|
console.log('Received:', value)
|
|
776
799
|
}
|
|
@@ -783,13 +806,13 @@ When requests don't rely on each other, you can make them in parallel with `Prom
|
|
|
783
806
|
```ts
|
|
784
807
|
const { data } = await useAsyncData(() => {
|
|
785
808
|
return Promise.all([
|
|
786
|
-
$fetch(
|
|
787
|
-
$fetch(
|
|
788
|
-
])
|
|
789
|
-
})
|
|
809
|
+
$fetch('/api/comments/'),
|
|
810
|
+
$fetch('/api/author/12'),
|
|
811
|
+
])
|
|
812
|
+
})
|
|
790
813
|
|
|
791
|
-
const comments = computed(() => data.value?.[0])
|
|
792
|
-
const author = computed(() => data.value?.[1])
|
|
814
|
+
const comments = computed(() => data.value?.[0])
|
|
815
|
+
const author = computed(() => data.value?.[1])
|
|
793
816
|
```
|
|
794
817
|
|
|
795
818
|
:video-accordion{title="Watch a video from Vue School on parallel data fetching" videoId="1024262536" platform="vimeo"}
|