@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.
Files changed (200) hide show
  1. package/1.getting-started/01.introduction.md +6 -6
  2. package/1.getting-started/02.installation.md +2 -1
  3. package/1.getting-started/03.configuration.md +36 -36
  4. package/1.getting-started/04.views.md +9 -9
  5. package/1.getting-started/05.assets.md +15 -9
  6. package/1.getting-started/06.styling.md +58 -48
  7. package/1.getting-started/07.routing.md +17 -17
  8. package/1.getting-started/08.seo-meta.md +59 -46
  9. package/1.getting-started/09.transitions.md +49 -44
  10. package/1.getting-started/10.data-fetching.md +104 -81
  11. package/1.getting-started/11.state-management.md +26 -19
  12. package/1.getting-started/12.error-handling.md +22 -20
  13. package/1.getting-started/13.server.md +8 -8
  14. package/1.getting-started/14.layers.md +22 -16
  15. package/1.getting-started/15.prerendering.md +32 -32
  16. package/1.getting-started/16.deployment.md +10 -10
  17. package/1.getting-started/17.testing.md +44 -44
  18. package/1.getting-started/18.upgrade.md +53 -71
  19. package/2.guide/0.index.md +7 -7
  20. package/2.guide/{2.directory-structure → 1.directory-structure}/.navigation.yml +1 -1
  21. package/2.guide/{2.directory-structure → 1.directory-structure}/0.nuxt.md +3 -3
  22. package/2.guide/1.directory-structure/0.output.md +18 -0
  23. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/.navigation.yml +1 -1
  24. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.assets.md +4 -4
  25. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.components.md +45 -28
  26. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.composables.md +13 -13
  27. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.layouts.md +19 -15
  28. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.middleware.md +31 -25
  29. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.pages.md +39 -37
  30. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.plugins.md +25 -25
  31. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/1.utils.md +7 -7
  32. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/3.app-config.md +18 -18
  33. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/3.app.md +7 -7
  34. package/2.guide/{2.directory-structure → 1.directory-structure}/1.app/3.error.md +6 -6
  35. package/2.guide/{2.directory-structure → 1.directory-structure}/1.content.md +7 -4
  36. package/2.guide/{2.directory-structure → 1.directory-structure}/1.modules.md +8 -8
  37. package/2.guide/{2.directory-structure → 1.directory-structure}/1.node_modules.md +2 -2
  38. package/2.guide/{2.directory-structure → 1.directory-structure}/1.public.md +2 -2
  39. package/2.guide/{2.directory-structure → 1.directory-structure}/1.server.md +35 -35
  40. package/2.guide/{2.directory-structure → 1.directory-structure}/1.shared.md +7 -7
  41. package/2.guide/{2.directory-structure → 1.directory-structure}/2.env.md +8 -8
  42. package/2.guide/{2.directory-structure → 1.directory-structure}/2.gitignore.md +1 -1
  43. package/2.guide/{2.directory-structure → 1.directory-structure}/2.nuxtignore.md +5 -4
  44. package/2.guide/{2.directory-structure → 1.directory-structure}/2.nuxtrc.md +4 -4
  45. package/2.guide/{2.directory-structure → 1.directory-structure}/3.nuxt-config.md +3 -3
  46. package/2.guide/{2.directory-structure → 1.directory-structure}/3.package.md +1 -1
  47. package/2.guide/{2.directory-structure → 1.directory-structure}/3.tsconfig.md +3 -3
  48. package/2.guide/{1.concepts → 2.concepts}/1.auto-imports.md +22 -22
  49. package/2.guide/{1.concepts → 2.concepts}/10.nuxt-lifecycle.md +17 -17
  50. package/2.guide/{1.concepts → 2.concepts}/2.vuejs-development.md +13 -13
  51. package/2.guide/{1.concepts → 2.concepts}/3.rendering.md +24 -22
  52. package/2.guide/{1.concepts → 2.concepts}/4.server-engine.md +6 -6
  53. package/2.guide/{1.concepts → 2.concepts}/5.modules.md +5 -5
  54. package/2.guide/{1.concepts → 2.concepts}/7.esm.md +17 -15
  55. package/2.guide/{1.concepts → 2.concepts}/8.typescript.md +12 -12
  56. package/2.guide/3.going-further/1.events.md +3 -3
  57. package/2.guide/3.going-further/1.experimental-features.md +246 -85
  58. package/2.guide/3.going-further/1.features.md +44 -9
  59. package/2.guide/3.going-further/1.internals.md +25 -25
  60. package/2.guide/3.going-further/10.runtime-config.md +12 -12
  61. package/2.guide/3.going-further/11.nightly-release-channel.md +1 -1
  62. package/2.guide/3.going-further/2.hooks.md +14 -14
  63. package/2.guide/3.going-further/3.modules.md +96 -94
  64. package/2.guide/3.going-further/4.kit.md +7 -7
  65. package/2.guide/3.going-further/6.nuxt-app.md +8 -8
  66. package/2.guide/3.going-further/7.layers.md +62 -53
  67. package/2.guide/3.going-further/9.debugging.md +2 -2
  68. package/2.guide/4.recipes/1.custom-routing.md +30 -30
  69. package/2.guide/4.recipes/2.vite-plugin.md +4 -4
  70. package/2.guide/4.recipes/3.custom-usefetch.md +13 -13
  71. package/2.guide/4.recipes/4.sessions-and-authentication.md +35 -21
  72. package/2.guide/5.best-practices/hydration.md +4 -4
  73. package/2.guide/5.best-practices/performance.md +17 -17
  74. package/3.api/1.components/1.client-only.md +6 -3
  75. package/3.api/1.components/1.nuxt-client-fallback.md +10 -7
  76. package/3.api/1.components/10.nuxt-picture.md +1 -1
  77. package/3.api/1.components/11.teleports.md +5 -2
  78. package/3.api/1.components/12.nuxt-route-announcer.md +9 -9
  79. package/3.api/1.components/13.nuxt-time.md +44 -17
  80. package/3.api/1.components/2.nuxt-page.md +6 -6
  81. package/3.api/1.components/3.nuxt-layout.md +15 -10
  82. package/3.api/1.components/4.nuxt-link.md +42 -22
  83. package/3.api/1.components/5.nuxt-loading-indicator.md +3 -3
  84. package/3.api/1.components/6.nuxt-error-boundary.md +12 -10
  85. package/3.api/2.composables/on-prehydrate.md +2 -2
  86. package/3.api/2.composables/use-app-config.md +1 -1
  87. package/3.api/2.composables/use-async-data.md +20 -20
  88. package/3.api/2.composables/use-cookie.md +29 -21
  89. package/3.api/2.composables/use-error.md +2 -2
  90. package/3.api/2.composables/use-fetch.md +58 -32
  91. package/3.api/2.composables/use-head-safe.md +7 -7
  92. package/3.api/2.composables/use-head.md +5 -5
  93. package/3.api/2.composables/use-hydration.md +6 -6
  94. package/3.api/2.composables/use-lazy-async-data.md +4 -4
  95. package/3.api/2.composables/use-lazy-fetch.md +4 -4
  96. package/3.api/2.composables/use-loading-indicator.md +12 -12
  97. package/3.api/2.composables/use-nuxt-app.md +22 -22
  98. package/3.api/2.composables/use-nuxt-data.md +8 -8
  99. package/3.api/2.composables/use-preview-mode.md +15 -18
  100. package/3.api/2.composables/use-request-event.md +1 -1
  101. package/3.api/2.composables/use-request-fetch.md +3 -3
  102. package/3.api/2.composables/use-request-header.md +1 -1
  103. package/3.api/2.composables/use-request-headers.md +4 -4
  104. package/3.api/2.composables/use-request-url.md +1 -1
  105. package/3.api/2.composables/use-response-header.md +9 -10
  106. package/3.api/2.composables/use-route-announcer.md +4 -4
  107. package/3.api/2.composables/use-route.md +1 -1
  108. package/3.api/2.composables/use-router.md +10 -8
  109. package/3.api/2.composables/use-runtime-config.md +11 -11
  110. package/3.api/2.composables/use-runtime-hook.md +2 -2
  111. package/3.api/2.composables/use-seo-meta.md +4 -4
  112. package/3.api/2.composables/use-server-seo-meta.md +6 -6
  113. package/3.api/2.composables/use-state.md +5 -5
  114. package/3.api/3.utils/$fetch.md +10 -8
  115. package/3.api/3.utils/abort-navigation.md +3 -3
  116. package/3.api/3.utils/add-route-middleware.md +5 -5
  117. package/3.api/3.utils/call-once.md +6 -6
  118. package/3.api/3.utils/clear-error.md +3 -3
  119. package/3.api/3.utils/clear-nuxt-data.md +3 -3
  120. package/3.api/3.utils/clear-nuxt-state.md +3 -3
  121. package/3.api/3.utils/create-error.md +2 -2
  122. package/3.api/3.utils/define-lazy-hydration-component.md +13 -13
  123. package/3.api/3.utils/define-nuxt-component.md +5 -5
  124. package/3.api/3.utils/define-nuxt-plugin.md +13 -13
  125. package/3.api/3.utils/define-nuxt-route-middleware.md +5 -5
  126. package/3.api/3.utils/define-page-meta.md +23 -23
  127. package/3.api/3.utils/define-route-rules.md +7 -7
  128. package/3.api/3.utils/navigate-to.md +11 -11
  129. package/3.api/3.utils/prefetch-components.md +1 -1
  130. package/3.api/3.utils/preload-components.md +1 -1
  131. package/3.api/3.utils/preload-route-components.md +2 -2
  132. package/3.api/3.utils/prerender-routes.md +3 -3
  133. package/3.api/3.utils/refresh-cookie.md +4 -4
  134. package/3.api/3.utils/refresh-nuxt-data.md +12 -7
  135. package/3.api/3.utils/reload-nuxt-app.md +3 -3
  136. package/3.api/3.utils/set-page-layout.md +1 -1
  137. package/3.api/3.utils/set-response-status.md +3 -3
  138. package/3.api/3.utils/show-error.md +5 -5
  139. package/3.api/3.utils/update-app-config.md +4 -3
  140. package/3.api/4.commands/add.md +1 -1
  141. package/3.api/4.commands/analyze.md +2 -1
  142. package/3.api/4.commands/build.md +2 -1
  143. package/3.api/4.commands/dev.md +5 -4
  144. package/3.api/4.commands/generate.md +3 -2
  145. package/3.api/4.commands/init.md +3 -2
  146. package/3.api/4.commands/module.md +4 -4
  147. package/3.api/4.commands/prepare.md +7 -2
  148. package/3.api/4.commands/preview.md +5 -4
  149. package/3.api/4.commands/test.md +40 -0
  150. package/3.api/4.commands/typecheck.md +5 -3
  151. package/3.api/4.commands/upgrade.md +3 -3
  152. package/3.api/5.kit/1.modules.md +36 -36
  153. package/3.api/5.kit/10.runtime-config.md +1 -1
  154. package/3.api/5.kit/10.templates.md +8 -6
  155. package/3.api/5.kit/11.nitro.md +62 -62
  156. package/3.api/5.kit/12.resolving.md +2 -2
  157. package/3.api/5.kit/14.builder.md +1 -0
  158. package/3.api/5.kit/15.examples.md +2 -2
  159. package/3.api/5.kit/16.layers.md +26 -26
  160. package/3.api/5.kit/3.compatibility.md +14 -14
  161. package/3.api/5.kit/4.autoimports.md +13 -13
  162. package/3.api/5.kit/5.components.md +7 -7
  163. package/3.api/5.kit/6.context.md +3 -3
  164. package/3.api/5.kit/7.pages.md +7 -7
  165. package/3.api/5.kit/8.layout.md +2 -2
  166. package/3.api/5.kit/9.plugins.md +5 -4
  167. package/3.api/6.advanced/1.hooks.md +3 -3
  168. package/3.api/6.advanced/2.import-meta.md +3 -3
  169. package/3.api/6.nuxt-config.md +300 -865
  170. package/3.api/index.md +7 -7
  171. package/5.community/2.getting-help.md +1 -1
  172. package/5.community/3.reporting-bugs.md +1 -1
  173. package/5.community/4.contribution.md +11 -11
  174. package/5.community/5.framework-contribution.md +4 -4
  175. package/5.community/6.roadmap.md +1 -1
  176. package/6.bridge/1.overview.md +13 -13
  177. package/6.bridge/10.configuration.md +2 -1
  178. package/6.bridge/2.typescript.md +3 -3
  179. package/6.bridge/3.bridge-composition-api.md +8 -8
  180. package/6.bridge/4.plugins-and-middleware.md +9 -9
  181. package/6.bridge/5.nuxt3-compatible-api.md +20 -17
  182. package/6.bridge/6.meta.md +20 -19
  183. package/6.bridge/7.runtime-config.md +1 -1
  184. package/6.bridge/8.nitro.md +3 -3
  185. package/6.bridge/9.vite.md +4 -4
  186. package/7.migration/1.overview.md +2 -2
  187. package/7.migration/10.bundling.md +1 -1
  188. package/7.migration/11.server.md +3 -3
  189. package/7.migration/2.configuration.md +23 -21
  190. package/7.migration/20.module-authors.md +7 -7
  191. package/7.migration/3.auto-imports.md +3 -3
  192. package/7.migration/4.meta.md +21 -18
  193. package/7.migration/5.plugins-and-middleware.md +8 -8
  194. package/7.migration/6.pages-and-layouts.md +28 -24
  195. package/7.migration/7.component-options.md +18 -18
  196. package/7.migration/8.runtime-config.md +7 -7
  197. package/package.json +1 -1
  198. package/2.guide/2.directory-structure/0.output.md +0 -18
  199. /package/2.guide/{1.concepts → 2.concepts}/.navigation.yml +0 -0
  200. /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()">Refresh data</button>
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 === '/') clear()
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 v-model="id" type="number" :disabled="pending"/>
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">Get data</button>
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: "Hello AI, how are you?",
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("/api/comments/"),
787
- $fetch("/api/author/12")
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"}