@nuxt/docs 3.19.1 → 3.19.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 +2 -2
- package/1.getting-started/02.installation.md +1 -0
- package/1.getting-started/03.configuration.md +29 -29
- package/1.getting-started/04.views.md +7 -7
- package/1.getting-started/05.assets.md +15 -9
- package/1.getting-started/06.styling.md +55 -45
- package/1.getting-started/07.routing.md +12 -12
- package/1.getting-started/08.seo-meta.md +55 -42
- package/1.getting-started/09.transitions.md +47 -42
- package/1.getting-started/10.data-fetching.md +90 -67
- package/1.getting-started/11.state-management.md +22 -15
- package/1.getting-started/12.error-handling.md +11 -9
- package/1.getting-started/13.server.md +3 -3
- package/1.getting-started/14.layers.md +21 -15
- package/1.getting-started/15.prerendering.md +28 -28
- package/1.getting-started/16.deployment.md +9 -9
- package/1.getting-started/17.testing.md +43 -43
- package/1.getting-started/18.upgrade.md +58 -57
- package/2.guide/0.index.md +3 -3
- 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/{2.directory-structure → 1.directory-structure}/0.output.md +3 -3
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.assets.md +3 -3
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.components.md +45 -24
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.composables.md +11 -11
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.content.md +7 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.layouts.md +16 -12
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.middleware.md +28 -22
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.modules.md +6 -6
- 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.pages.md +33 -31
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.plugins.md +25 -25
- 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 +34 -34
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.shared.md +6 -6
- package/2.guide/{2.directory-structure → 1.directory-structure}/1.utils.md +5 -5
- package/2.guide/{2.directory-structure → 1.directory-structure}/2.env.md +5 -5
- 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 +4 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/2.nuxtrc.md +3 -3
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.app-config.md +12 -12
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.app.md +4 -4
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.error.md +6 -6
- package/2.guide/{2.directory-structure → 1.directory-structure}/3.nuxt-config.md +2 -2
- 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 +18 -18
- package/2.guide/{1.concepts → 2.concepts}/10.nuxt-lifecycle.md +10 -10
- package/2.guide/{1.concepts → 2.concepts}/2.vuejs-development.md +9 -9
- package/2.guide/{1.concepts → 2.concepts}/3.rendering.md +21 -19
- package/2.guide/{1.concepts → 2.concepts}/4.server-engine.md +5 -5
- package/2.guide/{1.concepts → 2.concepts}/5.modules.md +4 -4
- package/2.guide/{1.concepts → 2.concepts}/7.esm.md +15 -13
- package/2.guide/{1.concepts → 2.concepts}/8.typescript.md +11 -11
- package/2.guide/3.going-further/1.events.md +2 -2
- package/2.guide/3.going-further/1.experimental-features.md +80 -80
- package/2.guide/3.going-further/1.features.md +15 -15
- package/2.guide/3.going-further/1.internals.md +25 -25
- package/2.guide/3.going-further/10.runtime-config.md +11 -11
- package/2.guide/3.going-further/2.hooks.md +11 -11
- package/2.guide/3.going-further/3.modules.md +89 -87
- package/2.guide/3.going-further/4.kit.md +5 -5
- package/2.guide/3.going-further/6.nuxt-app.md +5 -5
- package/2.guide/3.going-further/7.layers.md +61 -52
- package/2.guide/3.going-further/9.debugging.md +2 -2
- package/2.guide/4.recipes/1.custom-routing.md +31 -31
- package/2.guide/4.recipes/2.vite-plugin.md +4 -4
- package/2.guide/4.recipes/3.custom-usefetch.md +12 -12
- package/2.guide/4.recipes/4.sessions-and-authentication.md +34 -20
- package/2.guide/5.best-practices/hydration.md +4 -4
- package/2.guide/5.best-practices/performance.md +12 -12
- package/3.api/1.components/1.client-only.md +6 -3
- package/3.api/1.components/1.nuxt-client-fallback.md +9 -6
- package/3.api/1.components/10.nuxt-picture.md +1 -1
- package/3.api/1.components/11.teleports.md +4 -1
- 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 +4 -4
- package/3.api/1.components/3.nuxt-layout.md +11 -6
- package/3.api/1.components/4.nuxt-link.md +40 -20
- package/3.api/1.components/5.nuxt-loading-indicator.md +2 -2
- package/3.api/1.components/6.nuxt-error-boundary.md +11 -9
- package/3.api/2.composables/on-prehydrate.md +2 -2
- package/3.api/2.composables/use-async-data.md +17 -17
- package/3.api/2.composables/use-cookie.md +28 -20
- package/3.api/2.composables/use-error.md +1 -1
- package/3.api/2.composables/use-fetch.md +55 -29
- package/3.api/2.composables/use-head-safe.md +7 -7
- package/3.api/2.composables/use-head.md +4 -4
- package/3.api/2.composables/use-hydration.md +6 -6
- package/3.api/2.composables/use-lazy-async-data.md +2 -2
- package/3.api/2.composables/use-lazy-fetch.md +2 -2
- package/3.api/2.composables/use-loading-indicator.md +12 -12
- package/3.api/2.composables/use-nuxt-app.md +19 -19
- 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 +9 -7
- package/3.api/2.composables/use-runtime-config.md +6 -6
- package/3.api/2.composables/use-runtime-hook.md +2 -2
- package/3.api/2.composables/use-seo-meta.md +2 -2
- package/3.api/2.composables/use-server-seo-meta.md +4 -4
- package/3.api/2.composables/use-state.md +4 -4
- package/3.api/3.utils/$fetch.md +9 -7
- 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 +4 -4
- package/3.api/3.utils/clear-error.md +2 -2
- 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 +1 -1
- 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 +12 -12
- package/3.api/3.utils/define-nuxt-route-middleware.md +5 -5
- package/3.api/3.utils/define-page-meta.md +21 -21
- package/3.api/3.utils/define-route-rules.md +5 -5
- package/3.api/3.utils/navigate-to.md +10 -10
- 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/prerender-routes.md +3 -3
- package/3.api/3.utils/refresh-cookie.md +3 -3
- package/3.api/3.utils/refresh-nuxt-data.md +11 -6
- package/3.api/3.utils/reload-nuxt-app.md +2 -2
- package/3.api/3.utils/set-page-layout.md +1 -1
- package/3.api/3.utils/set-response-status.md +2 -2
- package/3.api/3.utils/show-error.md +4 -4
- package/3.api/3.utils/update-app-config.md +3 -2
- 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 +2 -1
- 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 +4 -2
- 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 +12 -12
- package/3.api/5.kit/4.autoimports.md +13 -13
- package/3.api/5.kit/5.components.md +7 -8
- 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 +6 -5
- package/3.api/6.advanced/1.hooks.md +2 -2
- package/3.api/6.advanced/2.import-meta.md +3 -3
- package/5.community/2.getting-help.md +1 -1
- package/5.community/3.reporting-bugs.md +1 -1
- package/5.community/4.contribution.md +6 -6
- package/5.community/5.framework-contribution.md +3 -3
- 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 +2 -2
- package/6.bridge/3.bridge-composition-api.md +6 -6
- package/6.bridge/4.plugins-and-middleware.md +9 -9
- package/6.bridge/5.nuxt3-compatible-api.md +19 -16
- package/6.bridge/6.meta.md +21 -20
- 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/2.configuration.md +22 -20
- package/7.migration/20.module-authors.md +6 -6
- package/7.migration/3.auto-imports.md +3 -3
- package/7.migration/4.meta.md +20 -17
- package/7.migration/5.plugins-and-middleware.md +5 -5
- package/7.migration/6.pages-and-layouts.md +23 -19
- package/7.migration/7.component-options.md +14 -14
- package/7.migration/8.runtime-config.md +6 -6
- package/package.json +1 -1
- /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/3.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/3.x/api/utils/dollarfetch) is the simplest way to make a network request.
|
|
12
|
+
- [`useFetch`](/docs/3.x/api/composables/use-fetch) is a wrapper around `$fetch` that fetches data only once in [universal rendering](/docs/3.x/guide/concepts/rendering#universal-rendering).
|
|
13
|
+
- [`useAsyncData`](/docs/3.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/3.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/3.x/api/composables/use-fetch) and [`useAsyncData`](/docs/3.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/3.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/3.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/3.x/api/components/nuxt-loading-indicator) to add a progress bar between page navigations.
|
|
63
63
|
::
|
|
64
64
|
|
|
65
65
|
## `$fetch`
|
|
@@ -68,12 +68,12 @@ 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>
|
|
@@ -90,11 +90,11 @@ Read more about `$fetch`.
|
|
|
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/3.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/3.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/3.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/3.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.vue]
|
|
136
136
|
<script setup lang="ts">
|
|
@@ -142,7 +142,7 @@ 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/3.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
|
|
|
@@ -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/3.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/3.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/3.x/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable.
|
|
165
165
|
|
|
166
166
|
```vue [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/3.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/3.x/api/composables/use-nuxt-data) or to [refresh specific data](/docs/3.x/api/utils/refresh-nuxt-data#refresh-specific-data).
|
|
181
181
|
::
|
|
182
182
|
|
|
183
183
|
```vue [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/3.x/api/utils/call-once) utility to do so.
|
|
212
212
|
|
|
213
213
|
```vue
|
|
214
214
|
<script setup lang="ts">
|
|
@@ -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/3.x/api/composables/use-async-data) and [`useFetch`](/docs/3.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.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/3.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">
|
|
@@ -303,7 +303,7 @@ 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
|
|
|
@@ -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/3.x/api/composables/use-fetch) and [`useAsyncData`](/docs/3.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/3.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/3.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/3.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,7 +426,9 @@ 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
|
```
|
|
@@ -434,7 +436,7 @@ const { data, error, execute, refresh } = await useFetch('/api/users')
|
|
|
434
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](#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/3.x/api/utils/clear-nuxt-data) and [`refreshNuxtData`](/docs/3.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,13 +478,28 @@ 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
486
|
If you need to change the URL based on a reactive value, you may want to use a [computed URL](#computed-url) instead.
|
|
483
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
|
+
```
|
|
502
|
+
|
|
484
503
|
#### Computed URL
|
|
485
504
|
|
|
486
505
|
Sometimes you may need to compute a URL from reactive values, and refresh the data each time these change. Instead of juggling your way around, you can attach each param as a reactive value. Nuxt will automatically use the reactive value and re-fetch each time it changes.
|
|
@@ -491,8 +510,8 @@ 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
|
```
|
|
@@ -506,16 +525,20 @@ Every time a dependency changes, the data will be fetched using the newly constr
|
|
|
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
|
|
@@ -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/3.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
|
```
|
|
@@ -636,9 +661,9 @@ Using `<script setup>` or `<script setup lang="ts">` are the recommended way of
|
|
|
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/3.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/3.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/3.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.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"}
|
|
@@ -4,14 +4,14 @@ description: Nuxt provides powerful state management libraries and the useState
|
|
|
4
4
|
navigation.icon: i-lucide-database
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Nuxt provides the [`useState`](/docs/api/composables/use-state) composable to create a reactive and SSR-friendly shared state across components.
|
|
7
|
+
Nuxt provides the [`useState`](/docs/3.x/api/composables/use-state) composable to create a reactive and SSR-friendly shared state across components.
|
|
8
8
|
|
|
9
|
-
[`useState`](/docs/api/composables/use-state) is an SSR-friendly [`ref`](https://vuejs.org/api/reactivity-core.html#ref) replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
|
|
9
|
+
[`useState`](/docs/3.x/api/composables/use-state) is an SSR-friendly [`ref`](https://vuejs.org/api/reactivity-core.html#ref) replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
|
|
10
10
|
|
|
11
11
|
:video-accordion{title="Watch a video from Alexander Lichter about why and when to use useState" videoId="mv0WcBABcIk"}
|
|
12
12
|
|
|
13
13
|
::important
|
|
14
|
-
Because the data inside [`useState`](/docs/api/composables/use-state) will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols.
|
|
14
|
+
Because the data inside [`useState`](/docs/3.x/api/composables/use-state) will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols.
|
|
15
15
|
::
|
|
16
16
|
|
|
17
17
|
::read-more{to="/docs/api/composables/use-state"}
|
|
@@ -56,12 +56,12 @@ const counter = useState('counter', () => Math.round(Math.random() * 1000))
|
|
|
56
56
|
:link-example{to="/docs/examples/features/state-management"}
|
|
57
57
|
|
|
58
58
|
::note
|
|
59
|
-
To globally invalidate cached state, see [`clearNuxtState`](/docs/api/utils/clear-nuxt-state) util.
|
|
59
|
+
To globally invalidate cached state, see [`clearNuxtState`](/docs/3.x/api/utils/clear-nuxt-state) util.
|
|
60
60
|
::
|
|
61
61
|
|
|
62
62
|
### Initializing State
|
|
63
63
|
|
|
64
|
-
Most of the time, you will want to initialize your state with data that resolves asynchronously. You can use the [`app.vue`](/docs/guide/directory-structure/app) component with the [`callOnce`](/docs/api/utils/call-once) util to do so.
|
|
64
|
+
Most of the time, you will want to initialize your state with data that resolves asynchronously. You can use the [`app.vue`](/docs/3.x/guide/directory-structure/app) component with the [`callOnce`](/docs/3.x/api/utils/call-once) util to do so.
|
|
65
65
|
|
|
66
66
|
```vue twoslash [app.vue]
|
|
67
67
|
<script setup lang="ts">
|
|
@@ -92,16 +92,16 @@ Make sure to install the Pinia module with `npx nuxt module add pinia` or follow
|
|
|
92
92
|
export const useWebsiteStore = defineStore('websiteStore', {
|
|
93
93
|
state: () => ({
|
|
94
94
|
name: '',
|
|
95
|
-
description: ''
|
|
95
|
+
description: '',
|
|
96
96
|
}),
|
|
97
97
|
actions: {
|
|
98
|
-
async fetch() {
|
|
98
|
+
async fetch () {
|
|
99
99
|
const infos = await $fetch('https://api.nuxt.com/modules/pinia')
|
|
100
100
|
|
|
101
101
|
this.name = infos.name
|
|
102
102
|
this.description = infos.description
|
|
103
|
-
}
|
|
104
|
-
}
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
105
|
})
|
|
106
106
|
```
|
|
107
107
|
```vue [app.vue]
|
|
@@ -151,8 +151,8 @@ export const useLocales = () => {
|
|
|
151
151
|
const locales = ref([
|
|
152
152
|
'en-US',
|
|
153
153
|
'en-GB',
|
|
154
|
-
|
|
155
|
-
'ja-JP-u-ca-japanese'
|
|
154
|
+
// ...,
|
|
155
|
+
'ja-JP-u-ca-japanese',
|
|
156
156
|
])
|
|
157
157
|
if (!locales.value.includes(locale.value)) {
|
|
158
158
|
locales.value.unshift(locale.value)
|
|
@@ -177,8 +177,15 @@ const date = useLocaleDate(new Date('2016-10-26'))
|
|
|
177
177
|
<h1>Nuxt birthday</h1>
|
|
178
178
|
<p>{{ date }}</p>
|
|
179
179
|
<label for="locale-chooser">Preview a different locale</label>
|
|
180
|
-
<select
|
|
181
|
-
|
|
180
|
+
<select
|
|
181
|
+
id="locale-chooser"
|
|
182
|
+
v-model="locale"
|
|
183
|
+
>
|
|
184
|
+
<option
|
|
185
|
+
v-for="loc of locales"
|
|
186
|
+
:key="loc"
|
|
187
|
+
:value="loc"
|
|
188
|
+
>
|
|
182
189
|
{{ loc }}
|
|
183
190
|
</option>
|
|
184
191
|
</select>
|
|
@@ -191,7 +198,7 @@ const date = useLocaleDate(new Date('2016-10-26'))
|
|
|
191
198
|
|
|
192
199
|
## Shared State
|
|
193
200
|
|
|
194
|
-
By using [auto-imported composables](/docs/guide/directory-structure/composables) we can define global type-safe states and import them across the app.
|
|
201
|
+
By using [auto-imported composables](/docs/3.x/guide/directory-structure/composables) we can define global type-safe states and import them across the app.
|
|
195
202
|
|
|
196
203
|
```ts twoslash [composables/states.ts]
|
|
197
204
|
export const useColor = () => useState<string>('color', () => 'pink')
|
|
@@ -214,7 +221,7 @@ const color = useColor() // Same as useState('color')
|
|
|
214
221
|
|
|
215
222
|
## Using third-party libraries
|
|
216
223
|
|
|
217
|
-
Nuxt **used to rely** on the Vuex library to provide global state management. If you are migrating from Nuxt 2, please head to [the migration guide](/docs/migration/configuration#vuex).
|
|
224
|
+
Nuxt **used to rely** on the Vuex library to provide global state management. If you are migrating from Nuxt 2, please head to [the migration guide](/docs/3.x/migration/configuration#vuex).
|
|
218
225
|
|
|
219
226
|
Nuxt is not opinionated about state management, so feel free to choose the right solution for your needs. There are multiple integrations with the most popular state management libraries, including:
|
|
220
227
|
|
|
@@ -8,7 +8,7 @@ Nuxt is a full-stack framework, which means there are several sources of unpreve
|
|
|
8
8
|
|
|
9
9
|
- Errors during the Vue rendering lifecycle (SSR & CSR)
|
|
10
10
|
- Server and client startup errors (SSR + CSR)
|
|
11
|
-
- Errors during Nitro server lifecycle ([`server/`](/docs/guide/directory-structure/server) directory)
|
|
11
|
+
- Errors during Nitro server lifecycle ([`server/`](/docs/3.x/guide/directory-structure/server) directory)
|
|
12
12
|
- Errors downloading JS chunks
|
|
13
13
|
|
|
14
14
|
::tip
|
|
@@ -19,7 +19,7 @@ Nuxt is a full-stack framework, which means there are several sources of unpreve
|
|
|
19
19
|
|
|
20
20
|
You can hook into Vue errors using [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured).
|
|
21
21
|
|
|
22
|
-
In addition, Nuxt provides a [`vue:error`](/docs/api/advanced/hooks#app-hooks-runtime) hook that will be called if any errors propagate up to the top level.
|
|
22
|
+
In addition, Nuxt provides a [`vue:error`](/docs/3.x/api/advanced/hooks#app-hooks-runtime) hook that will be called if any errors propagate up to the top level.
|
|
23
23
|
|
|
24
24
|
If you are using an error reporting framework, you can provide a global handler through [`vueApp.config.errorHandler`](https://vuejs.org/api/application.html#app-config-errorhandler). It will receive all Vue errors, even if they are handled.
|
|
25
25
|
|
|
@@ -45,7 +45,7 @@ Note that the `vue:error` hook is based on [`onErrorCaptured`](https://vuejs.org
|
|
|
45
45
|
Nuxt will call the `app:error` hook if there are any errors in starting your Nuxt application.
|
|
46
46
|
|
|
47
47
|
This includes:
|
|
48
|
-
- running [Nuxt plugins](/docs/guide/directory-structure/plugins)
|
|
48
|
+
- running [Nuxt plugins](/docs/3.x/guide/directory-structure/plugins)
|
|
49
49
|
- processing `app:created` and `app:beforeMount` hooks
|
|
50
50
|
- rendering your Vue app to HTML (during SSR)
|
|
51
51
|
- mounting the app (on client-side), though you should handle this case with `onErrorCaptured` or with `vue:error`
|
|
@@ -91,7 +91,7 @@ Customize the default error page by adding `~/error.vue` in the source directory
|
|
|
91
91
|
import type { NuxtError } from '#app'
|
|
92
92
|
|
|
93
93
|
const props = defineProps({
|
|
94
|
-
error: Object as () => NuxtError
|
|
94
|
+
error: Object as () => NuxtError,
|
|
95
95
|
})
|
|
96
96
|
|
|
97
97
|
const handleError = () => clearError({ redirect: '/' })
|
|
@@ -100,7 +100,9 @@ const handleError = () => clearError({ redirect: '/' })
|
|
|
100
100
|
<template>
|
|
101
101
|
<div>
|
|
102
102
|
<h2>{{ error?.statusCode }}</h2>
|
|
103
|
-
<button @click="handleError">
|
|
103
|
+
<button @click="handleError">
|
|
104
|
+
Clear errors
|
|
105
|
+
</button>
|
|
104
106
|
</div>
|
|
105
107
|
</template>
|
|
106
108
|
```
|
|
@@ -112,14 +114,14 @@ Read more about `error.vue` and its uses.
|
|
|
112
114
|
For custom errors we highly recommend using `onErrorCaptured` composable that can be called in a page/component setup function or `vue:error` runtime nuxt hook that can be configured in a nuxt plugin.
|
|
113
115
|
|
|
114
116
|
```ts twoslash [plugins/error-handler.ts]
|
|
115
|
-
export default defineNuxtPlugin(nuxtApp => {
|
|
117
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
116
118
|
nuxtApp.hook('vue:error', (err) => {
|
|
117
119
|
//
|
|
118
120
|
})
|
|
119
121
|
})
|
|
120
122
|
```
|
|
121
123
|
|
|
122
|
-
When you are ready to remove the error page, you can call the [`clearError`](/docs/api/utils/clear-error) helper function, which takes an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
|
|
124
|
+
When you are ready to remove the error page, you can call the [`clearError`](/docs/3.x/api/utils/clear-error) helper function, which takes an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
|
|
123
125
|
|
|
124
126
|
::important
|
|
125
127
|
Make sure to check before using anything dependent on Nuxt plugins, such as `$route` or `useRouter`, as if a plugin threw an error, then it won't be re-run until you clear the error.
|
|
@@ -167,7 +169,7 @@ const { data } = await useFetch(`/api/movies/${route.params.slug}`)
|
|
|
167
169
|
if (!data.value) {
|
|
168
170
|
throw createError({
|
|
169
171
|
statusCode: 404,
|
|
170
|
-
statusMessage: 'Page Not Found'
|
|
172
|
+
statusMessage: 'Page Not Found',
|
|
171
173
|
})
|
|
172
174
|
}
|
|
173
175
|
</script>
|
|
@@ -205,7 +207,7 @@ Read more about `clearError` util.
|
|
|
205
207
|
|
|
206
208
|
## Render Error in Component
|
|
207
209
|
|
|
208
|
-
Nuxt also provides a [`<NuxtErrorBoundary>`](/docs/api/components/nuxt-error-boundary) component that allows you to handle client-side errors within your app, without replacing your entire site with an error page.
|
|
210
|
+
Nuxt also provides a [`<NuxtErrorBoundary>`](/docs/3.x/api/components/nuxt-error-boundary) component that allows you to handle client-side errors within your app, without replacing your entire site with an error page.
|
|
209
211
|
|
|
210
212
|
This component is responsible for handling errors that occur within its default slot. On client-side, it will prevent the error from bubbling up to the top level, and will render the `#error` slot instead.
|
|
211
213
|
|