@nuxt/docs 4.2.0 → 4.2.2

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 (241) hide show
  1. package/1.getting-started/01.introduction.md +1 -1
  2. package/1.getting-started/02.installation.md +3 -3
  3. package/1.getting-started/03.configuration.md +27 -27
  4. package/1.getting-started/04.views.md +5 -5
  5. package/1.getting-started/05.assets.md +8 -8
  6. package/1.getting-started/06.styling.md +15 -15
  7. package/1.getting-started/07.routing.md +10 -6
  8. package/1.getting-started/08.seo-meta.md +3 -3
  9. package/1.getting-started/09.transitions.md +10 -10
  10. package/1.getting-started/10.data-fetching.md +16 -16
  11. package/1.getting-started/11.state-management.md +3 -3
  12. package/1.getting-started/12.error-handling.md +6 -6
  13. package/1.getting-started/13.server.md +6 -6
  14. package/1.getting-started/14.layers.md +32 -13
  15. package/1.getting-started/16.deployment.md +1 -1
  16. package/1.getting-started/17.testing.md +35 -4
  17. package/1.getting-started/18.upgrade.md +42 -34
  18. package/{2.guide/1.directory-structure → 2.directory-structure}/0.nuxt.md +1 -1
  19. package/{2.guide/1.directory-structure → 2.directory-structure}/0.output.md +1 -1
  20. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.assets.md +2 -2
  21. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.components.md +6 -6
  22. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.composables.md +2 -2
  23. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.layouts.md +3 -3
  24. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.middleware.md +5 -5
  25. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.pages.md +17 -17
  26. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.plugins.md +3 -7
  27. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.utils.md +3 -3
  28. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.app.md +4 -4
  29. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.error.md +1 -3
  30. package/{2.guide/1.directory-structure → 2.directory-structure}/1.content.md +2 -2
  31. package/{2.guide/1.directory-structure → 2.directory-structure}/1.modules.md +1 -1
  32. package/{2.guide/1.directory-structure → 2.directory-structure}/1.node_modules.md +2 -2
  33. package/{2.guide/1.directory-structure → 2.directory-structure}/1.public.md +1 -1
  34. package/{2.guide/1.directory-structure → 2.directory-structure}/1.server.md +7 -7
  35. package/{2.guide/1.directory-structure → 2.directory-structure}/1.shared.md +3 -3
  36. package/{2.guide/1.directory-structure → 2.directory-structure}/2.env.md +2 -2
  37. package/{2.guide/1.directory-structure → 2.directory-structure}/2.nuxtignore.md +1 -1
  38. package/{2.guide/1.directory-structure → 2.directory-structure}/2.nuxtrc.md +1 -1
  39. package/{2.guide/1.directory-structure → 2.directory-structure}/3.nuxt-config.md +1 -1
  40. package/{2.guide/1.directory-structure → 2.directory-structure}/3.package.md +1 -1
  41. package/2.directory-structure/3.tsconfig.md +69 -0
  42. package/2.directory-structure/index.md +61 -0
  43. package/{2.guide → 3.guide}/0.index.md +4 -7
  44. package/{2.guide/2.concepts/3.rendering.md → 3.guide/1.concepts/1.rendering.md} +4 -30
  45. package/{2.guide/2.concepts/2.vuejs-development.md → 3.guide/1.concepts/10.vuejs-development.md} +7 -6
  46. package/{2.guide/2.concepts/10.nuxt-lifecycle.md → 3.guide/1.concepts/2.nuxt-lifecycle.md} +32 -25
  47. package/{2.guide/2.concepts/1.auto-imports.md → 3.guide/1.concepts/3.auto-imports.md} +7 -7
  48. package/{2.guide/2.concepts → 3.guide/1.concepts}/4.server-engine.md +3 -3
  49. package/{2.guide/2.concepts → 3.guide/1.concepts}/5.modules.md +1 -1
  50. package/{2.guide/2.concepts → 3.guide/1.concepts}/7.esm.md +3 -2
  51. package/{2.guide/2.concepts → 3.guide/1.concepts}/8.typescript.md +15 -38
  52. package/{2.guide/2.concepts → 3.guide/1.concepts}/9.code-style.md +1 -1
  53. package/{2.guide/5.best-practices → 3.guide/2.best-practices}/hydration.md +1 -1
  54. package/{2.guide/5.best-practices → 3.guide/2.best-practices}/performance.md +2 -2
  55. package/3.guide/3.ai/.navigation.yml +3 -0
  56. package/3.guide/3.ai/1.mcp.md +255 -0
  57. package/3.guide/3.ai/2.llms-txt.md +65 -0
  58. package/{2.guide → 3.guide}/4.recipes/1.custom-routing.md +5 -5
  59. package/{2.guide → 3.guide}/4.recipes/2.vite-plugin.md +1 -1
  60. package/{2.guide → 3.guide}/4.recipes/3.custom-usefetch.md +1 -1
  61. package/{2.guide → 3.guide}/4.recipes/4.sessions-and-authentication.md +1 -1
  62. package/{2.guide/3.going-further → 3.guide/5.going-further}/1.events.md +2 -3
  63. package/{2.guide/3.going-further → 3.guide/5.going-further}/1.experimental-features.md +10 -10
  64. package/{2.guide/3.going-further → 3.guide/5.going-further}/1.features.md +1 -1
  65. package/{2.guide/3.going-further → 3.guide/5.going-further}/1.internals.md +3 -2
  66. package/{2.guide/3.going-further → 3.guide/5.going-further}/10.runtime-config.md +2 -2
  67. package/{2.guide/3.going-further → 3.guide/5.going-further}/2.hooks.md +2 -2
  68. package/{2.guide/3.going-further → 3.guide/5.going-further}/3.modules.md +78 -11
  69. package/{2.guide/3.going-further → 3.guide/5.going-further}/6.nuxt-app.md +5 -5
  70. package/{2.guide/3.going-further → 3.guide/5.going-further}/7.layers.md +42 -25
  71. package/{2.guide/3.going-further → 3.guide/5.going-further}/9.debugging.md +1 -1
  72. package/{3.api → 4.api}/1.components/10.nuxt-picture.md +1 -1
  73. package/{3.api → 4.api}/1.components/11.teleports.md +1 -1
  74. package/{3.api → 4.api}/1.components/12.nuxt-route-announcer.md +1 -3
  75. package/{3.api → 4.api}/1.components/13.nuxt-time.md +0 -2
  76. package/{3.api → 4.api}/1.components/2.nuxt-page.md +3 -3
  77. package/{3.api → 4.api}/1.components/3.nuxt-layout.md +5 -5
  78. package/{3.api → 4.api}/1.components/4.nuxt-link.md +11 -11
  79. package/{3.api → 4.api}/1.components/5.nuxt-loading-indicator.md +1 -1
  80. package/{3.api → 4.api}/1.components/6.nuxt-error-boundary.md +1 -1
  81. package/{3.api → 4.api}/1.components/7.nuxt-welcome.md +2 -2
  82. package/{3.api → 4.api}/2.composables/use-app-config.md +1 -1
  83. package/{3.api → 4.api}/2.composables/use-async-data.md +76 -13
  84. package/4.api/2.composables/use-cookie.md +183 -0
  85. package/{3.api → 4.api}/2.composables/use-fetch.md +33 -33
  86. package/{3.api → 4.api}/2.composables/use-head-safe.md +37 -20
  87. package/4.api/2.composables/use-head.md +169 -0
  88. package/{3.api → 4.api}/2.composables/use-hydration.md +24 -18
  89. package/4.api/2.composables/use-lazy-async-data.md +96 -0
  90. package/4.api/2.composables/use-lazy-fetch.md +111 -0
  91. package/{3.api → 4.api}/2.composables/use-nuxt-app.md +7 -7
  92. package/{3.api → 4.api}/2.composables/use-nuxt-data.md +1 -1
  93. package/{3.api → 4.api}/2.composables/use-request-fetch.md +1 -1
  94. package/{3.api → 4.api}/2.composables/use-response-header.md +1 -1
  95. package/{3.api → 4.api}/2.composables/use-route-announcer.md +0 -2
  96. package/{3.api → 4.api}/2.composables/use-route.md +2 -2
  97. package/4.api/2.composables/use-router.md +94 -0
  98. package/{3.api → 4.api}/2.composables/use-runtime-config.md +1 -1
  99. package/{3.api → 4.api}/2.composables/use-runtime-hook.md +1 -1
  100. package/{3.api → 4.api}/2.composables/use-state.md +1 -1
  101. package/{3.api → 4.api}/3.utils/$fetch.md +1 -1
  102. package/{3.api → 4.api}/3.utils/abort-navigation.md +3 -3
  103. package/{3.api → 4.api}/3.utils/add-route-middleware.md +1 -1
  104. package/{3.api → 4.api}/3.utils/call-once.md +0 -2
  105. package/{3.api → 4.api}/3.utils/define-lazy-hydration-component.md +4 -4
  106. package/{3.api → 4.api}/3.utils/define-nuxt-component.md +1 -1
  107. package/4.api/3.utils/define-nuxt-plugin.md +102 -0
  108. package/{3.api → 4.api}/3.utils/define-nuxt-route-middleware.md +2 -2
  109. package/{3.api → 4.api}/3.utils/define-page-meta.md +14 -14
  110. package/{3.api → 4.api}/3.utils/navigate-to.md +15 -15
  111. package/{3.api → 4.api}/3.utils/on-before-route-leave.md +1 -1
  112. package/{3.api → 4.api}/3.utils/on-before-route-update.md +1 -1
  113. package/{3.api → 4.api}/3.utils/refresh-cookie.md +1 -3
  114. package/{3.api → 4.api}/3.utils/update-app-config.md +2 -2
  115. package/{3.api → 4.api}/4.commands/add.md +10 -10
  116. package/4.api/4.commands/analyze.md +42 -0
  117. package/4.api/4.commands/build-module.md +42 -0
  118. package/4.api/4.commands/build.md +47 -0
  119. package/{3.api → 4.api}/4.commands/cleanup.md +6 -6
  120. package/4.api/4.commands/dev.md +60 -0
  121. package/{3.api → 4.api}/4.commands/devtools.md +7 -7
  122. package/4.api/4.commands/generate.md +42 -0
  123. package/4.api/4.commands/info.md +33 -0
  124. package/4.api/4.commands/init.md +50 -0
  125. package/4.api/4.commands/module.md +84 -0
  126. package/4.api/4.commands/prepare.md +41 -0
  127. package/4.api/4.commands/preview.md +44 -0
  128. package/4.api/4.commands/test.md +40 -0
  129. package/4.api/4.commands/typecheck.md +44 -0
  130. package/4.api/4.commands/upgrade.md +37 -0
  131. package/{3.api → 4.api}/5.kit/1.modules.md +18 -18
  132. package/{3.api → 4.api}/5.kit/10.templates.md +23 -23
  133. package/{3.api → 4.api}/5.kit/11.nitro.md +35 -35
  134. package/{3.api → 4.api}/5.kit/14.builder.md +21 -21
  135. package/{3.api → 4.api}/5.kit/16.layers.md +12 -12
  136. package/{3.api → 4.api}/5.kit/2.programmatic.md +2 -2
  137. package/{3.api → 4.api}/5.kit/4.autoimports.md +18 -18
  138. package/4.api/5.kit/5.components.md +146 -0
  139. package/4.api/6.advanced/1.hooks.md +105 -0
  140. package/{3.api → 4.api}/6.nuxt-config.md +29 -28
  141. package/5.community/3.reporting-bugs.md +1 -1
  142. package/5.community/4.contribution.md +1 -1
  143. package/5.community/5.framework-contribution.md +8 -8
  144. package/5.community/6.roadmap.md +25 -25
  145. package/5.community/7.changelog.md +10 -0
  146. package/6.bridge/1.overview.md +1 -1
  147. package/6.bridge/2.typescript.md +1 -1
  148. package/6.bridge/3.bridge-composition-api.md +1 -1
  149. package/6.bridge/4.plugins-and-middleware.md +2 -2
  150. package/7.migration/11.server.md +1 -1
  151. package/7.migration/2.configuration.md +3 -3
  152. package/7.migration/20.module-authors.md +1 -1
  153. package/7.migration/3.auto-imports.md +1 -1
  154. package/7.migration/5.plugins-and-middleware.md +2 -2
  155. package/7.migration/6.pages-and-layouts.md +6 -6
  156. package/README.md +1 -1
  157. package/package.json +1 -1
  158. package/2.guide/1.directory-structure/3.tsconfig.md +0 -38
  159. package/3.api/2.composables/use-cookie.md +0 -183
  160. package/3.api/2.composables/use-head.md +0 -69
  161. package/3.api/2.composables/use-lazy-async-data.md +0 -47
  162. package/3.api/2.composables/use-lazy-fetch.md +0 -55
  163. package/3.api/2.composables/use-router.md +0 -94
  164. package/3.api/3.utils/define-nuxt-plugin.md +0 -102
  165. package/3.api/4.commands/analyze.md +0 -42
  166. package/3.api/4.commands/build-module.md +0 -42
  167. package/3.api/4.commands/build.md +0 -47
  168. package/3.api/4.commands/dev.md +0 -60
  169. package/3.api/4.commands/generate.md +0 -42
  170. package/3.api/4.commands/info.md +0 -33
  171. package/3.api/4.commands/init.md +0 -50
  172. package/3.api/4.commands/module.md +0 -84
  173. package/3.api/4.commands/prepare.md +0 -41
  174. package/3.api/4.commands/preview.md +0 -44
  175. package/3.api/4.commands/test.md +0 -40
  176. package/3.api/4.commands/typecheck.md +0 -44
  177. package/3.api/4.commands/upgrade.md +0 -37
  178. package/3.api/5.kit/5.components.md +0 -146
  179. package/3.api/6.advanced/1.hooks.md +0 -105
  180. /package/{2.guide/1.directory-structure → 2.directory-structure}/.navigation.yml +0 -0
  181. /package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/.navigation.yml +0 -0
  182. /package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.app-config.md +0 -0
  183. /package/{2.guide/1.directory-structure → 2.directory-structure}/2.gitignore.md +0 -0
  184. /package/{2.guide → 3.guide}/.navigation.yml +0 -0
  185. /package/{2.guide/2.concepts → 3.guide/1.concepts}/.navigation.yml +0 -0
  186. /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/.navigation.yml +0 -0
  187. /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/plugins.md +0 -0
  188. /package/{2.guide → 3.guide}/4.recipes/.navigation.yml +0 -0
  189. /package/{2.guide/3.going-further → 3.guide/5.going-further}/.navigation.yml +0 -0
  190. /package/{2.guide/3.going-further → 3.guide/5.going-further}/11.nightly-release-channel.md +0 -0
  191. /package/{2.guide/3.going-further → 3.guide/5.going-further}/4.kit.md +0 -0
  192. /package/{2.guide/3.going-further → 3.guide/5.going-further}/index.md +0 -0
  193. /package/{3.api → 4.api}/.navigation.yml +0 -0
  194. /package/{3.api → 4.api}/1.components/.navigation.yml +0 -0
  195. /package/{3.api → 4.api}/1.components/1.client-only.md +0 -0
  196. /package/{3.api → 4.api}/1.components/1.dev-only.md +0 -0
  197. /package/{3.api → 4.api}/1.components/1.nuxt-client-fallback.md +0 -0
  198. /package/{3.api → 4.api}/1.components/8.nuxt-island.md +0 -0
  199. /package/{3.api → 4.api}/1.components/9.nuxt-img.md +0 -0
  200. /package/{3.api → 4.api}/2.composables/.navigation.yml +0 -0
  201. /package/{3.api → 4.api}/2.composables/on-prehydrate.md +0 -0
  202. /package/{3.api → 4.api}/2.composables/use-error.md +0 -0
  203. /package/{3.api → 4.api}/2.composables/use-loading-indicator.md +0 -0
  204. /package/{3.api → 4.api}/2.composables/use-preview-mode.md +0 -0
  205. /package/{3.api → 4.api}/2.composables/use-request-event.md +0 -0
  206. /package/{3.api → 4.api}/2.composables/use-request-header.md +0 -0
  207. /package/{3.api → 4.api}/2.composables/use-request-headers.md +0 -0
  208. /package/{3.api → 4.api}/2.composables/use-request-url.md +0 -0
  209. /package/{3.api → 4.api}/2.composables/use-seo-meta.md +0 -0
  210. /package/{3.api → 4.api}/2.composables/use-server-seo-meta.md +0 -0
  211. /package/{3.api → 4.api}/3.utils/.navigation.yml +0 -0
  212. /package/{3.api → 4.api}/3.utils/clear-error.md +0 -0
  213. /package/{3.api → 4.api}/3.utils/clear-nuxt-data.md +0 -0
  214. /package/{3.api → 4.api}/3.utils/clear-nuxt-state.md +0 -0
  215. /package/{3.api → 4.api}/3.utils/create-error.md +0 -0
  216. /package/{3.api → 4.api}/3.utils/define-route-rules.md +0 -0
  217. /package/{3.api → 4.api}/3.utils/on-nuxt-ready.md +0 -0
  218. /package/{3.api → 4.api}/3.utils/prefetch-components.md +0 -0
  219. /package/{3.api → 4.api}/3.utils/preload-components.md +0 -0
  220. /package/{3.api → 4.api}/3.utils/preload-route-components.md +0 -0
  221. /package/{3.api → 4.api}/3.utils/prerender-routes.md +0 -0
  222. /package/{3.api → 4.api}/3.utils/refresh-nuxt-data.md +0 -0
  223. /package/{3.api → 4.api}/3.utils/reload-nuxt-app.md +0 -0
  224. /package/{3.api → 4.api}/3.utils/set-page-layout.md +0 -0
  225. /package/{3.api → 4.api}/3.utils/set-response-status.md +0 -0
  226. /package/{3.api → 4.api}/3.utils/show-error.md +0 -0
  227. /package/{3.api → 4.api}/4.commands/.navigation.yml +0 -0
  228. /package/{3.api → 4.api}/5.kit/.navigation.yml +0 -0
  229. /package/{3.api → 4.api}/5.kit/10.runtime-config.md +0 -0
  230. /package/{3.api → 4.api}/5.kit/12.resolving.md +0 -0
  231. /package/{3.api → 4.api}/5.kit/13.logging.md +0 -0
  232. /package/{3.api → 4.api}/5.kit/15.examples.md +0 -0
  233. /package/{3.api → 4.api}/5.kit/3.compatibility.md +0 -0
  234. /package/{3.api → 4.api}/5.kit/6.context.md +0 -0
  235. /package/{3.api → 4.api}/5.kit/7.pages.md +0 -0
  236. /package/{3.api → 4.api}/5.kit/8.layout.md +0 -0
  237. /package/{3.api → 4.api}/5.kit/9.head.md +0 -0
  238. /package/{3.api → 4.api}/5.kit/9.plugins.md +0 -0
  239. /package/{3.api → 4.api}/6.advanced/.navigation.yml +0 -0
  240. /package/{3.api → 4.api}/6.advanced/2.import-meta.md +0 -0
  241. /package/{3.api → 4.api}/index.md +0 -0
@@ -18,9 +18,9 @@ Within your pages, components, and plugins you can use useAsyncData to get acces
18
18
 
19
19
  ```vue [app/pages/index.vue]
20
20
  <script setup lang="ts">
21
- const { data, status, error, refresh, clear } = await useAsyncData(
21
+ const { data, status, pending, error, refresh, clear } = await useAsyncData(
22
22
  'mountains',
23
- () => $fetch('https://api.nuxtjs.dev/mountains'),
23
+ (_nuxtApp, { signal }) => $fetch('https://api.nuxtjs.dev/mountains', { signal }),
24
24
  )
25
25
  </script>
26
26
  ```
@@ -30,7 +30,7 @@ If you're using a custom useAsyncData wrapper, do not await it in the composable
30
30
  ::
31
31
 
32
32
  ::note
33
- `data`, `status` and `error` are Vue refs and they should be accessed with `.value` when used within the `<script setup>`, while `refresh`/`execute` and `clear` are plain functions.
33
+ `data`, `status`, `pending` and `error` are Vue refs and they should be accessed with `.value` when used within the `<script setup>`, while `refresh`/`execute` and `clear` are plain functions.
34
34
  ::
35
35
 
36
36
  ### Watch Params
@@ -42,10 +42,11 @@ The built-in `watch` option allows automatically rerunning the fetcher function
42
42
  const page = ref(1)
43
43
  const { data: posts } = await useAsyncData(
44
44
  'posts',
45
- () => $fetch('https://fakeApi.com/posts', {
45
+ (_nuxtApp, { signal }) => $fetch('https://fakeApi.com/posts', {
46
46
  params: {
47
47
  page: page.value,
48
48
  },
49
+ signal,
49
50
  }), {
50
51
  watch: [page],
51
52
  },
@@ -70,6 +71,64 @@ const { data: user } = useAsyncData(
70
71
  </script>
71
72
  ```
72
73
 
74
+ ### Make your `handler` abortable
75
+
76
+ You can make your `handler` function abortable by using the `signal` provided in the second argument. This is useful for cancelling requests when they are no longer needed, such as when a user navigates away from a page. `$fetch` natively supports abort signals.
77
+
78
+ ```ts
79
+ const { data, error } = await useAsyncData(
80
+ 'users',
81
+ (_nuxtApp, { signal }) => $fetch('/api/users', { signal }),
82
+ )
83
+
84
+ refresh() // will actually cancel the $fetch request (if dedupe: cancel)
85
+ refresh() // will actually cancel the $fetch request (if dedupe: cancel)
86
+ refresh()
87
+
88
+ clear() // will cancel the latest pending handler
89
+ ```
90
+
91
+ You can also pass an `AbortSignal` to the `refresh`/`execute` function to cancel individual requests manually.
92
+
93
+ ```ts
94
+ const { refresh } = await useAsyncData(
95
+ 'users',
96
+ (_nuxtApp, { signal }) => $fetch('/api/users', { signal }),
97
+ )
98
+ let abortController: AbortController | undefined
99
+
100
+ function handleUserAction () {
101
+ abortController = new AbortController()
102
+ refresh({ signal: abortController.signal })
103
+ }
104
+
105
+ function handleCancel () {
106
+ abortController?.abort() // aborts the ongoing refresh request
107
+ }
108
+ ```
109
+
110
+ If your `handler` function does not support abort signals, you can implement your own abort logic using the `signal` provided.
111
+
112
+ ```ts
113
+ const { data, error } = await useAsyncData(
114
+ 'users',
115
+ (_nuxtApp, { signal }) => {
116
+ return new Promise((resolve, reject) => {
117
+ signal?.addEventListener('abort', () => {
118
+ reject(new Error('Request aborted'))
119
+ })
120
+ return Promise.resolve(callback.call(this, yourHandler)).then(resolve, reject)
121
+ })
122
+ },
123
+ )
124
+ ```
125
+
126
+ The handler signal will be aborted when:
127
+
128
+ - A new request is made with `dedupe: 'cancel'`
129
+ - The `clear` function is called
130
+ - The `options.timeout` duration is exceeded
131
+
73
132
  ::warning
74
133
  [`useAsyncData`](/docs/4.x/api/composables/use-async-data) is a reserved function name transformed by the compiler, so you should not name your own function [`useAsyncData`](/docs/4.x/api/composables/use-async-data).
75
134
  ::
@@ -116,7 +175,7 @@ You can use `useLazyAsyncData` to have the same behavior as `lazy: true` with `u
116
175
 
117
176
  ### Shared State and Option Consistency
118
177
 
119
- When using the same key for multiple `useAsyncData` calls, they will share the same `data`, `error` and `status` refs. This ensures consistency across components but requires option consistency.
178
+ When using the same key for multiple `useAsyncData` calls, they will share the same `data`, `error`, `status` and `pending` refs. This ensures consistency across components but requires option consistency.
120
179
 
121
180
  The following options **must be consistent** across all calls with the same key:
122
181
  - `handler` function
@@ -135,12 +194,12 @@ The following options **can differ** without triggering warnings:
135
194
 
136
195
  ```ts
137
196
  // ❌ This will trigger a development warning
138
- const { data: users1 } = useAsyncData('users', () => $fetch('/api/users'), { deep: false })
139
- const { data: users2 } = useAsyncData('users', () => $fetch('/api/users'), { deep: true })
197
+ const { data: users1 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { deep: false })
198
+ const { data: users2 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { deep: true })
140
199
 
141
200
  // ✅ This is allowed
142
- const { data: users1 } = useAsyncData('users', () => $fetch('/api/users'), { immediate: true })
143
- const { data: users2 } = useAsyncData('users', () => $fetch('/api/users'), { immediate: false })
201
+ const { data: users1 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { immediate: true })
202
+ const { data: users2 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { immediate: false })
144
203
  ```
145
204
 
146
205
  ::tip
@@ -159,6 +218,7 @@ Keyed state created using `useAsyncData` can be retrieved across your Nuxt appli
159
218
  - `pending`: the request is in progress
160
219
  - `success`: the request has completed successfully
161
220
  - `error`: the request has failed
221
+ - `pending`: a `Ref<boolean>` that is `true` while the request is in progress (that is, while `status.value === 'pending'`).
162
222
  - `clear`: a function that can be used to set `data` to `undefined` (or the value of `options.default()` if provided), set `error` to `undefined`, set `status` to `idle`, and mark any currently pending requests as cancelled.
163
223
 
164
224
  By default, Nuxt waits until a `refresh` is finished before it can be executed again.
@@ -170,14 +230,16 @@ If you have not fetched data on the server (for example, with `server: false`),
170
230
  ## Type
171
231
 
172
232
  ```ts [Signature]
233
+ export type AsyncDataHandler<ResT> = (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<ResT>
234
+
173
235
  export function useAsyncData<DataT, DataE> (
174
- handler: (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<DataT>,
175
- options?: AsyncDataOptions<DataT>
236
+ handler: AsyncDataHandler<DataT>,
237
+ options?: AsyncDataOptions<DataT>,
176
238
  ): AsyncData<DataT, DataE>
177
239
  export function useAsyncData<DataT, DataE> (
178
240
  key: MaybeRefOrGetter<string>,
179
- handler: (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<DataT>,
180
- options?: AsyncDataOptions<DataT>
241
+ handler: AsyncDataHandler<DataT>,
242
+ options?: AsyncDataOptions<DataT>,
181
243
  ): Promise<AsyncData<DataT, DataE>>
182
244
 
183
245
  type AsyncDataOptions<DataT> = {
@@ -206,6 +268,7 @@ type AsyncData<DataT, ErrorT> = {
206
268
  clear: () => void
207
269
  error: Ref<ErrorT | undefined>
208
270
  status: Ref<AsyncDataRequestStatus>
271
+ pending: Ref<boolean>
209
272
  }
210
273
 
211
274
  interface AsyncDataExecuteOptions {
@@ -0,0 +1,183 @@
1
+ ---
2
+ title: 'useCookie'
3
+ description: useCookie is an SSR-friendly composable to read and write cookies.
4
+ links:
5
+ - label: Source
6
+ icon: i-simple-icons-github
7
+ to: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/cookie.ts
8
+ size: xs
9
+ ---
10
+
11
+ ## Usage
12
+
13
+ Within your pages, components, and plugins, you can use `useCookie` to read and write cookies in an SSR-friendly way.
14
+
15
+ ```ts
16
+ const cookie = useCookie(name, options)
17
+ ```
18
+
19
+ ::note
20
+ `useCookie` only works in the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context).
21
+ ::
22
+
23
+ ::tip
24
+ The returned ref will automatically serialize and deserialize cookie values to JSON.
25
+ ::
26
+
27
+ ## Type
28
+
29
+ ```ts [Signature]
30
+ import type { Ref } from 'vue'
31
+ import type { CookieParseOptions, CookieSerializeOptions } from 'cookie-es'
32
+
33
+ export interface CookieOptions<T = any> extends Omit<CookieSerializeOptions & CookieParseOptions, 'decode' | 'encode'> {
34
+ decode?(value: string): T
35
+ encode?(value: T): string
36
+ default?: () => T | Ref<T>
37
+ watch?: boolean | 'shallow'
38
+ readonly?: boolean
39
+ }
40
+
41
+ export interface CookieRef<T> extends Ref<T> {}
42
+
43
+ export function useCookie<T = string | null | undefined> (
44
+ name: string,
45
+ options?: CookieOptions<T>,
46
+ ): CookieRef<T>
47
+ ```
48
+
49
+ ## Parameters
50
+
51
+ `name`: The name of the cookie.
52
+
53
+ `options`: Options to control cookie behavior. The object can have the following properties:
54
+
55
+ Most of the options will be directly passed to the [cookie](https://github.com/jshttp/cookie) package.
56
+
57
+ | Property | Type | Default | Description |
58
+ |---------------|------------------------|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
59
+ | `decode` | `(value: string) => T` | `decodeURIComponent` + [destr](https://github.com/unjs/destr). | Custom function to decode the cookie value. Since the value of a cookie has a limited character set (and must be a simple string), this function can be used to decode a previously encoded cookie value into a JavaScript string or other object. <br/> **Note:** If an error is thrown from this function, the original, non-decoded cookie value will be returned as the cookie's value. |
60
+ | `encode` | `(value: T) => string` | `JSON.stringify` + `encodeURIComponent` | Custom function to encode the cookie value. Since the value of a cookie has a limited character set (and must be a simple string), this function can be used to encode a value into a string suited for a cookie's value. |
61
+ | `default` | `() => T \| Ref<T>` | `undefined` | Function returning the default value if the cookie does not exist. The function can also return a `Ref`. |
62
+ | `watch` | `boolean \| 'shallow'` | `true` | Whether to watch for changes and update the cookie. `true` for deep watch, `'shallow'` for shallow watch, i.e. data changes for only top level properties, `false` to disable. <br/> **Note:** Refresh `useCookie` values manually when a cookie has changed with [`refreshCookie`](/docs/4.x/api/utils/refresh-cookie). |
63
+ | `readonly` | `boolean` | `false` | If `true`, disables writing to the cookie. |
64
+ | `maxAge` | `number` | `undefined` | Max age in seconds for the cookie, i.e. the value for the [`Max-Age` `Set-Cookie` attribute](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.2). The given number will be converted to an integer by rounding down. By default, no maximum age is set. |
65
+ | `expires` | `Date` | `undefined` | Expiration date for the cookie. By default, no expiration is set. Most clients will consider this a "non-persistent cookie" and will delete it on a condition like exiting a web browser application. <br/> **Note:** The [cookie storage model specification](https://datatracker.ietf.org/doc/html/rfc6265#section-5.3) states that if both `expires` and `maxAge` is set, then `maxAge` takes precedence, but not all clients may obey this, so if both are set, they should point to the same date and time! <br/>If neither of `expires` and `maxAge` is set, the cookie will be session-only and removed when the user closes their browser. |
66
+ | `httpOnly` | `boolean` | `false` | Sets the HttpOnly attribute. <br/> **Note:** Be careful when setting this to `true`, as compliant clients will not allow client-side JavaScript to see the cookie in `document.cookie`. |
67
+ | `secure` | `boolean` | `false` | Sets the [`Secure` `Set-Cookie` attribute](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.5). <br/>**Note:** Be careful when setting this to `true`, as compliant clients will not send the cookie back to the server in the future if the browser does not have an HTTPS connection. This can lead to hydration errors. |
68
+ | `partitioned` | `boolean` | `false` | Sets the [`Partitioned` `Set-Cookie` attribute](https://datatracker.ietf.org/doc/html/draft-cutler-httpbis-partitioned-cookies#section-2.1). <br/>**Note:** This is an attribute that has not yet been fully standardized, and may change in the future. <br/>This also means many clients may ignore this attribute until they understand it.<br/>More information can be found in the [proposal](https://github.com/privacycg/CHIPS). |
69
+ | `domain` | `string` | `undefined` | Sets the [`Domain` `Set-Cookie` attribute](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3). By default, no domain is set, and most clients will consider applying the cookie only to the current domain. |
70
+ | `path` | `string` | `'/'` | Sets the [`Path` `Set-Cookie` attribute](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.4). By default, the path is considered the ["default path"](https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4). |
71
+ | `sameSite` | `boolean \| string` | `undefined` | Sets the [`SameSite` `Set-Cookie` attribute](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7). <br/>- `true` will set the `SameSite` attribute to `Strict` for strict same-site enforcement.<br/>- `false` will not set the `SameSite` attribute.<br/>- `'lax'` will set the `SameSite` attribute to `Lax` for lax same-site enforcement.<br/>- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.<br/>- `'strict'` will set the `SameSite` attribute to `Strict` for strict same-site enforcement. |
72
+
73
+ ## Return Values
74
+
75
+ Returns a Vue `Ref<T>` representing the cookie value. Updating the ref will update the cookie (unless `readonly` is set). The ref is SSR-friendly and will work on both client and server.
76
+
77
+ ## Examples
78
+
79
+ ### Basic Usage
80
+
81
+ The example below creates a cookie called `counter`. If the cookie doesn't exist, it is initially set to a random value. Whenever we update the `counter` variable, the cookie will be updated accordingly.
82
+
83
+ ```vue [app/app.vue]
84
+ <script setup lang="ts">
85
+ const counter = useCookie('counter')
86
+
87
+ counter.value ||= Math.round(Math.random() * 1000)
88
+ </script>
89
+
90
+ <template>
91
+ <div>
92
+ <h1>Counter: {{ counter || '-' }}</h1>
93
+ <button @click="counter = null">
94
+ reset
95
+ </button>
96
+ <button @click="counter--">
97
+ -
98
+ </button>
99
+ <button @click="counter++">
100
+ +
101
+ </button>
102
+ </div>
103
+ </template>
104
+ ```
105
+
106
+ ### Readonly Cookies
107
+
108
+ ```vue
109
+ <script setup lang="ts">
110
+ const user = useCookie(
111
+ 'userInfo',
112
+ {
113
+ default: () => ({ score: -1 }),
114
+ watch: false,
115
+ },
116
+ )
117
+
118
+ if (user.value) {
119
+ // the actual `userInfo` cookie will not be updated
120
+ user.value.score++
121
+ }
122
+ </script>
123
+
124
+ <template>
125
+ <div>User score: {{ user?.score }}</div>
126
+ </template>
127
+ ```
128
+
129
+ ### Writable Cookies
130
+
131
+ ```vue
132
+ <script setup lang="ts">
133
+ const list = useCookie(
134
+ 'list',
135
+ {
136
+ default: () => [],
137
+ watch: 'shallow',
138
+ },
139
+ )
140
+
141
+ function add () {
142
+ list.value?.push(Math.round(Math.random() * 1000))
143
+ // list cookie won't be updated with this change
144
+ }
145
+
146
+ function save () {
147
+ // the actual `list` cookie will be updated
148
+ list.value &&= [...list.value]
149
+ }
150
+ </script>
151
+
152
+ <template>
153
+ <div>
154
+ <h1>List</h1>
155
+ <pre>{{ list }}</pre>
156
+ <button @click="add">
157
+ Add
158
+ </button>
159
+ <button @click="save">
160
+ Save
161
+ </button>
162
+ </div>
163
+ </template>
164
+ ```
165
+
166
+ ### Cookies in API Routes
167
+
168
+ You can use `getCookie` and `setCookie` from [`h3`](https://github.com/h3js/h3) package to set cookies in server API routes.
169
+
170
+ ```ts [server/api/counter.ts]
171
+ export default defineEventHandler((event) => {
172
+ // Read counter cookie
173
+ let counter = getCookie(event, 'counter') || 0
174
+
175
+ // Increase counter cookie by 1
176
+ setCookie(event, 'counter', ++counter)
177
+
178
+ // Send JSON response
179
+ return { counter }
180
+ })
181
+ ```
182
+
183
+ :link-example{to="/docs/4.x/examples/advanced/use-cookie"}
@@ -100,7 +100,7 @@ If you encounter the `data` variable destructured from a `useFetch` returns a st
100
100
 
101
101
  ### Reactive Fetch Options
102
102
 
103
- Fetch options can be provided as reactive, supporting `computed`, `ref` and [computed getters](https://vuejs.org/guide/essentials/computed.html). When a reactive fetch option is updated it will trigger a refetch using the updated resolved reactive value.
103
+ Fetch options can be provided as reactive, supporting `computed`, `ref` and [computed getters](https://vuejs.org/guide/essentials/computed). When a reactive fetch option is updated it will trigger a refetch using the updated resolved reactive value.
104
104
 
105
105
  ```ts
106
106
  const searchQuery = ref('initial')
@@ -128,7 +128,7 @@ searchQuery.value = 'new search'
128
128
  ```ts [Signature]
129
129
  export function useFetch<DataT, ErrorT> (
130
130
  url: string | Request | Ref<string | Request> | (() => string | Request),
131
- options?: UseFetchOptions<DataT>
131
+ options?: UseFetchOptions<DataT>,
132
132
  ): Promise<AsyncData<DataT, ErrorT>>
133
133
 
134
134
  type UseFetchOptions<DataT> = {
@@ -183,29 +183,29 @@ type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
183
183
 
184
184
  - `options` (object): Configuration for the fetch request. Extends [unjs/ofetch](https://github.com/unjs/ofetch) options and [`AsyncDataOptions`](/docs/4.x/api/composables/use-async-data#params). All options can be a static value, a `ref`, or a computed value.
185
185
 
186
- | Option | Type | Default | Description |
187
- | ---| --- | --- | --- |
188
- | `key` | `MaybeRefOrGetter<string>` | auto-gen | Unique key for de-duplication. If not provided, generated from URL and options. |
189
- | `method` | `MaybeRefOrGetter<string>` | `'GET'` | HTTP request method. |
190
- | `query` | `MaybeRefOrGetter<SearchParams>` | - | Query/search params to append to the URL. Alias: `params`. |
191
- | `params` | `MaybeRefOrGetter<SearchParams>` | - | Alias for `query`. |
192
- | `body` | `MaybeRefOrGetter<RequestInit['body'] \| Record<string, any>>` | - | Request body. Objects are automatically stringified. |
193
- | `headers` | `MaybeRefOrGetter<Record<string, string> \| [key, value][] \| Headers>` | - | Request headers. |
194
- | `baseURL` | `MaybeRefOrGetter<string>` | - | Base URL for the request. |
195
- | `timeout` | `MaybeRefOrGetter<number>` | - | Timeout in milliseconds to abort the request. |
196
- | `cache` | `boolean \| string` | - | Cache control. Boolean disables cache, or use Fetch API values: `default`, `no-store`, etc. |
197
- | `server` | `boolean` | `true` | Whether to fetch on the server. |
198
- | `lazy` | `boolean` | `false` | If true, resolves after route loads (does not block navigation). |
199
- | `immediate` | `boolean` | `true` | If false, prevents request from firing immediately. |
200
- | `default` | `() => DataT` | - | Factory for default value of `data` before async resolves. |
201
- | `timeout` | `number` | - | A number in milliseconds to wait before timing out the request (defaults to `undefined`, which means no timeout) |
202
- | `transform` | `(input: DataT) => DataT \| Promise<DataT>` | - | Function to transform the result after resolving. |
203
- | `getCachedData`| `(key, nuxtApp, ctx) => DataT \| undefined` | - | Function to return cached data. See below for default. |
204
- | `pick` | `string[]` | - | Only pick specified keys from the result. |
205
- | `watch` | `MultiWatchSources \| false` | - | Array of reactive sources to watch and auto-refresh. `false` disables watching. |
206
- | `deep` | `boolean` | `false` | Return data in a deep ref object. |
207
- | `dedupe` | `'cancel' \| 'defer'` | `'cancel'` | Avoid fetching same key more than once at a time. |
208
- | `$fetch` | `typeof globalThis.$fetch` | - | Custom $fetch implementation. See [Custom useFetch in Nuxt](/docs/4.x/guide/recipes/custom-usefetch) |
186
+ | Option | Type | Default | Description |
187
+ |-----------------|-------------------------------------------------------------------------|------------|------------------------------------------------------------------------------------------------------------------|
188
+ | `key` | `MaybeRefOrGetter<string>` | auto-gen | Unique key for de-duplication. If not provided, generated from URL and options. |
189
+ | `method` | `MaybeRefOrGetter<string>` | `'GET'` | HTTP request method. |
190
+ | `query` | `MaybeRefOrGetter<SearchParams>` | - | Query/search params to append to the URL. Alias: `params`. |
191
+ | `params` | `MaybeRefOrGetter<SearchParams>` | - | Alias for `query`. |
192
+ | `body` | `MaybeRefOrGetter<RequestInit['body'] \| Record<string, any>>` | - | Request body. Objects are automatically stringified. |
193
+ | `headers` | `MaybeRefOrGetter<Record<string, string> \| [key, value][] \| Headers>` | - | Request headers. |
194
+ | `baseURL` | `MaybeRefOrGetter<string>` | - | Base URL for the request. |
195
+ | `timeout` | `MaybeRefOrGetter<number>` | - | Timeout in milliseconds to abort the request. |
196
+ | `cache` | `boolean \| string` | - | Cache control. Boolean disables cache, or use Fetch API values: `default`, `no-store`, etc. |
197
+ | `server` | `boolean` | `true` | Whether to fetch on the server. |
198
+ | `lazy` | `boolean` | `false` | If true, resolves after route loads (does not block navigation). |
199
+ | `immediate` | `boolean` | `true` | If false, prevents request from firing immediately. |
200
+ | `default` | `() => DataT` | - | Factory for default value of `data` before async resolves. |
201
+ | `timeout` | `number` | - | A number in milliseconds to wait before timing out the request (defaults to `undefined`, which means no timeout) |
202
+ | `transform` | `(input: DataT) => DataT \| Promise<DataT>` | - | Function to transform the result after resolving. |
203
+ | `getCachedData` | `(key, nuxtApp, ctx) => DataT \| undefined` | - | Function to return cached data. See below for default. |
204
+ | `pick` | `string[]` | - | Only pick specified keys from the result. |
205
+ | `watch` | `MultiWatchSources \| false` | - | Array of reactive sources to watch and auto-refresh. `false` disables watching. |
206
+ | `deep` | `boolean` | `false` | Return data in a deep ref object. |
207
+ | `dedupe` | `'cancel' \| 'defer'` | `'cancel'` | Avoid fetching same key more than once at a time. |
208
+ | `$fetch` | `typeof globalThis.$fetch` | - | Custom $fetch implementation. See [Custom useFetch in Nuxt](/docs/4.x/guide/recipes/custom-usefetch) |
209
209
 
210
210
  ::note
211
211
  All fetch options can be given a `computed` or `ref` value. These will be watched and new requests made automatically with any new values if they are updated.
@@ -222,14 +222,14 @@ This only caches data when `experimental.payloadExtraction` in `nuxt.config` is
222
222
 
223
223
  ## Return Values
224
224
 
225
- | Name | Type | Description |
226
- | --- | --- |--- |
227
- | `data` | `Ref<DataT \| undefined>` | The result of the asynchronous fetch. |
228
- | `refresh` | `(opts?: AsyncDataExecuteOptions) => Promise<void>` | Function to manually refresh the data. By default, Nuxt waits until a `refresh` is finished before it can be executed again. |
229
- | `execute` | `(opts?: AsyncDataExecuteOptions) => Promise<void>` | Alias for `refresh`. |
230
- | `error` | `Ref<ErrorT \| undefined>` | Error object if the data fetching failed. |
231
- | `status` | `Ref<'idle' \| 'pending' \| 'success' \| 'error'>` | Status of the data request. See below for possible values. |
232
- | `clear` | `() => void` | Resets `data` to `undefined` (or the value of `options.default()` if provided), `error` to `undefined`, set `status` to `idle`, and cancels any pending requests. |
225
+ | Name | Type | Description |
226
+ |-----------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
227
+ | `data` | `Ref<DataT \| undefined>` | The result of the asynchronous fetch. |
228
+ | `refresh` | `(opts?: AsyncDataExecuteOptions) => Promise<void>` | Function to manually refresh the data. By default, Nuxt waits until a `refresh` is finished before it can be executed again. |
229
+ | `execute` | `(opts?: AsyncDataExecuteOptions) => Promise<void>` | Alias for `refresh`. |
230
+ | `error` | `Ref<ErrorT \| undefined>` | Error object if the data fetching failed. |
231
+ | `status` | `Ref<'idle' \| 'pending' \| 'success' \| 'error'>` | Status of the data request. See below for possible values. |
232
+ | `clear` | `() => void` | Resets `data` to `undefined` (or the value of `options.default()` if provided), `error` to `undefined`, set `status` to `idle`, and cancels any pending requests. |
233
233
 
234
234
  ### Status values
235
235
 
@@ -8,28 +8,12 @@ links:
8
8
  size: xs
9
9
  ---
10
10
 
11
- The `useHeadSafe` composable is a wrapper around the [`useHead`](/docs/4.x/api/composables/use-head) composable that restricts the input to only allow safe values.
12
-
13
11
  ## Usage
14
12
 
15
- You can pass all the same values as [`useHead`](/docs/4.x/api/composables/use-head)
16
-
17
- ```ts
18
- useHeadSafe({
19
- script: [
20
- { id: 'xss-script', innerHTML: 'alert("xss")' },
21
- ],
22
- meta: [
23
- { 'http-equiv': 'refresh', 'content': '0;javascript:alert(1)' },
24
- ],
25
- })
26
- // Will safely generate
27
- // <script id="xss-script"></script>
28
- // <meta content="0;javascript:alert(1)">
29
- ```
13
+ The `useHeadSafe` composable is a wrapper around the [`useHead`](/docs/4.x/api/composables/use-head) composable that restricts the input to only allow safe values. This is the recommended way to manage head data when working with user input, as it prevents XSS attacks by sanitizing potentially dangerous attributes.
30
14
 
31
- ::read-more{to="https://unhead.unjs.io/docs/typescript/head/api/composables/use-head-safe" target="_blank"}
32
- Read more on the `Unhead` documentation.
15
+ ::warning
16
+ When using `useHeadSafe`, potentially dangerous attributes like `innerHTML` in scripts or `http-equiv` in meta tags are automatically stripped out to prevent XSS attacks. Use this composable whenever you're working with user-generated content.
33
17
  ::
34
18
 
35
19
  ## Type
@@ -38,7 +22,9 @@ Read more on the `Unhead` documentation.
38
22
  export function useHeadSafe (input: MaybeComputedRef<HeadSafe>): void
39
23
  ```
40
24
 
41
- The list of allowed values is:
25
+ ### Allowed Attributes
26
+
27
+ The following attributes are whitelisted for each head element type:
42
28
 
43
29
  ```ts
44
30
  const WhitelistAttributes = {
@@ -53,3 +39,34 @@ const WhitelistAttributes = {
53
39
  ```
54
40
 
55
41
  See [@unhead/vue](https://github.com/unjs/unhead/blob/main/packages/vue/src/types/safeSchema.ts) for more detailed types.
42
+
43
+ ## Parameters
44
+
45
+ `input`: A `MaybeComputedRef<HeadSafe>` object containing head data. You can pass all the same values as [`useHead`](/docs/4.x/api/composables/use-head), but only safe attributes will be rendered.
46
+
47
+ ## Return Values
48
+
49
+ This composable does not return any value.
50
+
51
+ ## Example
52
+
53
+ ```vue [app/pages/user-profile.vue]
54
+ <script setup lang="ts">
55
+ // User-generated content that might contain malicious code
56
+ const userBio = ref('<script>alert("xss")<' + '/script>')
57
+
58
+ useHeadSafe({
59
+ title: `User Profile`,
60
+ meta: [
61
+ {
62
+ name: 'description',
63
+ content: userBio.value, // Safely sanitized
64
+ },
65
+ ],
66
+ })
67
+ </script>
68
+ ```
69
+
70
+ ::read-more{to="https://unhead.unjs.io/docs/typescript/head/api/composables/use-head-safe" target="_blank"}
71
+ Read more on the `Unhead` documentation.
72
+ ::