@nuxt/docs 4.1.3 → 4.2.1
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/02.installation.md +4 -4
- package/1.getting-started/03.configuration.md +4 -4
- package/1.getting-started/04.views.md +2 -2
- package/1.getting-started/05.assets.md +1 -1
- package/1.getting-started/06.styling.md +11 -11
- package/1.getting-started/07.routing.md +4 -0
- package/1.getting-started/09.transitions.md +6 -6
- package/1.getting-started/10.data-fetching.md +14 -14
- package/1.getting-started/11.state-management.md +2 -2
- package/1.getting-started/12.error-handling.md +4 -4
- package/1.getting-started/13.server.md +4 -4
- package/1.getting-started/14.layers.md +29 -10
- package/1.getting-started/17.testing.md +3 -3
- package/1.getting-started/18.upgrade.md +205 -48
- package/2.guide/1.directory-structure/1.app/1.components.md +4 -4
- package/2.guide/1.directory-structure/1.app/1.composables.md +1 -1
- package/2.guide/1.directory-structure/1.app/1.layouts.md +2 -2
- package/2.guide/1.directory-structure/1.app/1.middleware.md +4 -4
- package/2.guide/1.directory-structure/1.app/1.pages.md +13 -13
- package/2.guide/1.directory-structure/1.app/1.plugins.md +1 -5
- package/2.guide/1.directory-structure/1.node_modules.md +1 -1
- package/2.guide/1.directory-structure/1.public.md +1 -1
- package/2.guide/1.directory-structure/1.server.md +5 -5
- package/2.guide/1.directory-structure/2.env.md +1 -1
- package/2.guide/1.directory-structure/3.tsconfig.md +38 -7
- package/2.guide/2.concepts/1.auto-imports.md +2 -2
- package/2.guide/2.concepts/10.nuxt-lifecycle.md +3 -3
- package/2.guide/2.concepts/2.vuejs-development.md +3 -3
- package/2.guide/2.concepts/3.rendering.md +4 -4
- package/2.guide/2.concepts/7.esm.md +7 -3
- package/2.guide/2.concepts/8.typescript.md +15 -38
- package/2.guide/2.concepts/9.code-style.md +1 -1
- package/2.guide/3.going-further/1.experimental-features.md +94 -6
- package/2.guide/3.going-further/1.features.md +15 -3
- package/2.guide/3.going-further/1.internals.md +2 -2
- package/2.guide/3.going-further/2.hooks.md +1 -1
- package/2.guide/3.going-further/3.modules.md +112 -29
- package/2.guide/3.going-further/6.nuxt-app.md +5 -5
- package/2.guide/3.going-further/7.layers.md +46 -21
- package/2.guide/3.going-further/9.debugging.md +1 -1
- package/2.guide/4.recipes/1.custom-routing.md +4 -4
- package/2.guide/4.recipes/2.vite-plugin.md +41 -0
- package/2.guide/4.recipes/3.custom-usefetch.md +1 -1
- package/2.guide/5.best-practices/hydration.md +1 -1
- package/3.api/1.components/10.nuxt-picture.md +1 -1
- package/3.api/1.components/11.teleports.md +1 -1
- package/3.api/1.components/12.nuxt-route-announcer.md +1 -1
- package/3.api/1.components/13.nuxt-time.md +5 -1
- package/3.api/1.components/2.nuxt-page.md +1 -1
- package/3.api/1.components/4.nuxt-link.md +11 -11
- package/3.api/1.components/5.nuxt-loading-indicator.md +1 -1
- package/3.api/1.components/6.nuxt-error-boundary.md +1 -1
- package/3.api/2.composables/use-app-config.md +1 -1
- package/3.api/2.composables/use-async-data.md +80 -13
- package/3.api/2.composables/use-cookie.md +7 -7
- package/3.api/2.composables/use-fetch.md +6 -2
- package/3.api/2.composables/use-head-safe.md +37 -20
- package/3.api/2.composables/use-head.md +136 -36
- package/3.api/2.composables/use-hydration.md +24 -18
- package/3.api/2.composables/use-lazy-async-data.md +58 -9
- package/3.api/2.composables/use-lazy-fetch.md +65 -9
- package/3.api/2.composables/use-nuxt-app.md +7 -7
- package/3.api/2.composables/use-nuxt-data.md +1 -1
- package/3.api/2.composables/use-request-fetch.md +1 -1
- package/3.api/2.composables/use-route.md +1 -1
- package/3.api/2.composables/use-router.md +15 -15
- package/3.api/2.composables/use-runtime-hook.md +1 -1
- package/3.api/2.composables/use-state.md +1 -1
- package/3.api/3.utils/abort-navigation.md +2 -2
- package/3.api/3.utils/define-lazy-hydration-component.md +4 -4
- package/3.api/3.utils/define-nuxt-component.md +1 -1
- package/3.api/3.utils/define-nuxt-plugin.md +1 -1
- package/3.api/3.utils/define-nuxt-route-middleware.md +1 -1
- package/3.api/3.utils/define-page-meta.md +8 -8
- package/3.api/3.utils/navigate-to.md +5 -5
- package/3.api/3.utils/on-before-route-leave.md +1 -1
- package/3.api/3.utils/on-before-route-update.md +1 -1
- package/3.api/3.utils/refresh-cookie.md +1 -1
- package/3.api/3.utils/update-app-config.md +2 -2
- package/3.api/5.kit/1.modules.md +88 -2
- package/3.api/5.kit/11.nitro.md +4 -0
- package/3.api/5.kit/14.builder.md +66 -10
- package/3.api/5.kit/15.examples.md +3 -5
- package/3.api/5.kit/2.programmatic.md +2 -2
- package/3.api/5.kit/5.components.md +1 -0
- package/3.api/5.kit/9.head.md +132 -0
- package/3.api/6.advanced/1.hooks.md +7 -7
- package/3.api/6.nuxt-config.md +100 -29
- package/5.community/3.reporting-bugs.md +3 -3
- package/5.community/4.contribution.md +1 -1
- package/5.community/5.framework-contribution.md +8 -8
- package/5.community/6.roadmap.md +4 -4
- package/6.bridge/4.plugins-and-middleware.md +1 -1
- package/7.migration/2.configuration.md +2 -2
- package/7.migration/20.module-authors.md +1 -1
- package/7.migration/5.plugins-and-middleware.md +1 -1
- package/7.migration/6.pages-and-layouts.md +2 -2
- package/README.md +1 -1
- package/package.json +1 -1
|
@@ -34,6 +34,146 @@ bun x nuxt upgrade
|
|
|
34
34
|
|
|
35
35
|
To use the latest Nuxt build and test features before their release, read about the [nightly release channel](/docs/4.x/guide/going-further/nightly-release-channel) guide.
|
|
36
36
|
|
|
37
|
+
## Testing Nuxt 5
|
|
38
|
+
|
|
39
|
+
Nuxt 5 is **currently in development**. Until the release, it is possible to test many of Nuxt 5's breaking changes from Nuxt version 4.2+.
|
|
40
|
+
|
|
41
|
+
### Opting in to Nuxt 5
|
|
42
|
+
|
|
43
|
+
First, upgrade Nuxt to the [latest release](https://github.com/nuxt/nuxt/releases).
|
|
44
|
+
|
|
45
|
+
Then you can set your `future.compatibilityVersion` to match Nuxt 5 behavior:
|
|
46
|
+
|
|
47
|
+
```ts twoslash [nuxt.config.ts]
|
|
48
|
+
export default defineNuxtConfig({
|
|
49
|
+
future: {
|
|
50
|
+
compatibilityVersion: 5,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
When you set your `future.compatibilityVersion` to `5`, defaults throughout your Nuxt configuration will change to opt in to Nuxt v5 behavior, including:
|
|
56
|
+
|
|
57
|
+
- **Vite Environment API**: Automatically enables the new [Vite Environment API](/docs/4.x/getting-started/upgrade#migration-to-vite-environment-api) for improved build configuration
|
|
58
|
+
- Other Nuxt 5 improvements and changes as they become available
|
|
59
|
+
|
|
60
|
+
::note
|
|
61
|
+
This section is subject to change until the final release, so please check back here regularly if you are testing Nuxt 5 using `future.compatibilityVersion: 5`.
|
|
62
|
+
::
|
|
63
|
+
|
|
64
|
+
Breaking or significant changes will be noted below along with migration steps for backward/forward compatibility.
|
|
65
|
+
|
|
66
|
+
### Migration to Vite Environment API
|
|
67
|
+
|
|
68
|
+
🚦 **Impact Level**: Medium
|
|
69
|
+
|
|
70
|
+
#### What Changed
|
|
71
|
+
|
|
72
|
+
Nuxt 5 migrates to Vite 6's new [Environment API](https://vite.dev/guide/api-environment), which formalizes the concept of environments and provides better control over configuration per environment.
|
|
73
|
+
|
|
74
|
+
Previously, Nuxt used separate client and server Vite configurations. Now, Nuxt uses a shared Vite configuration with environment-specific plugins that use the `applyToEnvironment()` method to target specific environments.
|
|
75
|
+
|
|
76
|
+
::tip
|
|
77
|
+
You can test this feature early by setting `future.compatibilityVersion: 5` (see [Testing Nuxt 5](/docs/4.x/getting-started/upgrade#testing-nuxt-5)) or by enabling it explicitly with `experimental.viteEnvironmentApi: true`.
|
|
78
|
+
::
|
|
79
|
+
|
|
80
|
+
**Key changes:**
|
|
81
|
+
|
|
82
|
+
1. **Deprecated environment-specific `extendViteConfig()`**: The `server` and `client` options in `extendViteConfig()` are deprecated and will show warnings when used.
|
|
83
|
+
|
|
84
|
+
2. **Changed plugin registration**: Vite plugins registered with `addVitePlugin()` and only targeting one environment (by passing `server: false` or `client: false`) will not have their `config` or `configResolved` hooks called.
|
|
85
|
+
|
|
86
|
+
3. **Shared configuration**: The `vite:extendConfig` and `vite:configResolved` hooks now work with a shared configuration rather than separate client/server configs.
|
|
87
|
+
|
|
88
|
+
#### Reasons for Change
|
|
89
|
+
|
|
90
|
+
The Vite Environment API provides:
|
|
91
|
+
- Better consistency between development and production builds
|
|
92
|
+
- More granular control over environment-specific configuration
|
|
93
|
+
- Improved performance and plugin architecture
|
|
94
|
+
- Support for custom environments beyond just client and server
|
|
95
|
+
|
|
96
|
+
#### Migration Steps
|
|
97
|
+
|
|
98
|
+
##### 1. Migrate to use Vite plugins
|
|
99
|
+
|
|
100
|
+
We would recommend you use a Vite plugin instead of `extendViteConfig`, `vite:configResolved` and `vite:extendConfig`.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// Before
|
|
104
|
+
extendViteConfig((config) => {
|
|
105
|
+
config.optimizeDeps.include.push('my-package')
|
|
106
|
+
}, { server: false })
|
|
107
|
+
|
|
108
|
+
nuxt.hook('vite:extendConfig' /* or vite:configResolved */, (config, { isClient }) => {
|
|
109
|
+
if (isClient) {
|
|
110
|
+
config.optimizeDeps.include.push('my-package')
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// After
|
|
115
|
+
addVitePlugin(() => ({
|
|
116
|
+
name: 'my-plugin',
|
|
117
|
+
config (config) {
|
|
118
|
+
// you can set global vite configuration here
|
|
119
|
+
},
|
|
120
|
+
configResolved (config) {
|
|
121
|
+
// you can access the fully resolved vite configuration here
|
|
122
|
+
},
|
|
123
|
+
configEnvironment (name, config) {
|
|
124
|
+
// you can set environment-specific vite configuration here
|
|
125
|
+
if (name === 'client') {
|
|
126
|
+
config.optimizeDeps ||= {}
|
|
127
|
+
config.optimizeDeps.include ||= []
|
|
128
|
+
config.optimizeDeps.include.push('my-package')
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
applyToEnvironment (environment) {
|
|
132
|
+
return environment.name === 'client'
|
|
133
|
+
},
|
|
134
|
+
}))
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
##### 2. Migrate Vite plugins to use environments
|
|
138
|
+
|
|
139
|
+
Instead of using `addVitePlugin` with `server: false` or `client: false`, you can instead use the new `applyToEnvironment` hook within your plugin.
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
// Before
|
|
143
|
+
addVitePlugin(() => ({
|
|
144
|
+
name: 'my-plugin',
|
|
145
|
+
config (config) {
|
|
146
|
+
config.optimizeDeps.include.push('my-package')
|
|
147
|
+
},
|
|
148
|
+
}), { client: false })
|
|
149
|
+
|
|
150
|
+
// After
|
|
151
|
+
addVitePlugin(() => ({
|
|
152
|
+
name: 'my-plugin',
|
|
153
|
+
config (config) {
|
|
154
|
+
// you can set global vite configuration here
|
|
155
|
+
},
|
|
156
|
+
configResolved (config) {
|
|
157
|
+
// you can access the fully resolved vite configuration here
|
|
158
|
+
},
|
|
159
|
+
configEnvironment (name, config) {
|
|
160
|
+
// you can set environment-specific vite configuration here
|
|
161
|
+
if (name === 'client') {
|
|
162
|
+
config.optimizeDeps ||= {}
|
|
163
|
+
config.optimizeDeps.include ||= []
|
|
164
|
+
config.optimizeDeps.include.push('my-package')
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
applyToEnvironment (environment) {
|
|
168
|
+
return environment.name === 'client'
|
|
169
|
+
},
|
|
170
|
+
}))
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
::read-more{to="https://vite.dev/guide/api-environment" target="_blank"}
|
|
174
|
+
Learn more about Vite's Environment API
|
|
175
|
+
::
|
|
176
|
+
|
|
37
177
|
## Migrating to Nuxt 4
|
|
38
178
|
|
|
39
179
|
Nuxt 4 includes significant improvements and changes. This guide will help you migrate your existing Nuxt 3 application to Nuxt 4.
|
|
@@ -74,26 +214,30 @@ To facilitate the upgrade process, we have collaborated with the [Codemod](https
|
|
|
74
214
|
If you encounter any issues, please report them to the Codemod team with `npx codemod feedback` 🙏
|
|
75
215
|
::
|
|
76
216
|
|
|
77
|
-
For a complete list of Nuxt 4 codemods, detailed information on each, their source, and various ways to run them, visit the [Codemod Registry](https://
|
|
217
|
+
For a complete list of Nuxt 4 codemods, detailed information on each, their source, and various ways to run them, visit the [Codemod Registry](https://app.codemod.com/registry).
|
|
78
218
|
|
|
79
219
|
You can run all the codemods mentioned in this guide using the following `codemod` recipe:
|
|
80
220
|
|
|
81
221
|
::code-group
|
|
82
222
|
|
|
83
223
|
```bash [npm]
|
|
84
|
-
|
|
224
|
+
# Using pinned version due to https://github.com/codemod-com/codemod/issues/1710
|
|
225
|
+
npx codemod@0.18.7 nuxt/4/migration-recipe
|
|
85
226
|
```
|
|
86
227
|
|
|
87
228
|
```bash [yarn]
|
|
88
|
-
|
|
229
|
+
# Using pinned version due to https://github.com/codemod-com/codemod/issues/1710
|
|
230
|
+
yarn dlx codemod@0.18.7 nuxt/4/migration-recipe
|
|
89
231
|
```
|
|
90
232
|
|
|
91
233
|
```bash [pnpm]
|
|
92
|
-
|
|
234
|
+
# Using pinned version due to https://github.com/codemod-com/codemod/issues/1710
|
|
235
|
+
pnpm dlx codemod@0.18.7 nuxt/4/migration-recipe
|
|
93
236
|
```
|
|
94
237
|
|
|
95
238
|
```bash [bun]
|
|
96
|
-
|
|
239
|
+
# Using pinned version due to https://github.com/codemod-com/codemod/issues/1710
|
|
240
|
+
bun x codemod@0.18.7 nuxt/4/migration-recipe
|
|
97
241
|
```
|
|
98
242
|
|
|
99
243
|
::
|
|
@@ -110,11 +254,11 @@ Nuxt now defaults to a new directory structure, with backwards compatibility (so
|
|
|
110
254
|
|
|
111
255
|
#### What Changed
|
|
112
256
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
257
|
+
- the new Nuxt default `srcDir` is `app/` by default, and most things are resolved from there.
|
|
258
|
+
- `serverDir` now defaults to `<rootDir>/server` rather than `<srcDir>/server`
|
|
259
|
+
- `layers/`, `modules/` and `public/` are resolved relative to `<rootDir>` by default
|
|
260
|
+
- if using [Nuxt Content v2.13+](https://github.com/nuxt/content/pull/2649), `content/` is resolved relative to `<rootDir>`
|
|
261
|
+
- a new `dir.app` is added, which is the directory we look for `router.options.ts` and `spa-loading-template.html` - this defaults to `<srcDir>/`
|
|
118
262
|
|
|
119
263
|
<details>
|
|
120
264
|
|
|
@@ -279,15 +423,15 @@ Now modules are loaded in the correct order:
|
|
|
279
423
|
2. **Project modules last** (highest priority)
|
|
280
424
|
|
|
281
425
|
This affects both:
|
|
282
|
-
|
|
283
|
-
|
|
426
|
+
- Modules defined in the `modules` array in `nuxt.config.ts`
|
|
427
|
+
- Auto-discovered modules from the `modules/` directory
|
|
284
428
|
|
|
285
429
|
#### Reasons for Change
|
|
286
430
|
|
|
287
431
|
This change ensures that:
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
432
|
+
- Extended layers have lower priority than the consuming project
|
|
433
|
+
- Module execution order matches the intuitive layer inheritance pattern
|
|
434
|
+
- Module configuration and hooks work as expected in multi-layer setups
|
|
291
435
|
|
|
292
436
|
#### Migration Steps
|
|
293
437
|
|
|
@@ -394,9 +538,9 @@ export default defineNuxtConfig({
|
|
|
394
538
|
[Unhead](https://unhead.unjs.io/), used to generate `<head>` tags, has been updated to version 2. While mostly compatible it includes several breaking changes
|
|
395
539
|
for lower-level APIs.
|
|
396
540
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
541
|
+
- Removed props: `vmid`, `hid`, `children`, `body`.
|
|
542
|
+
- Promise input no longer supported.
|
|
543
|
+
- Tags are now sorted using Capo.js by default.
|
|
400
544
|
|
|
401
545
|
#### Migration Steps
|
|
402
546
|
|
|
@@ -404,7 +548,7 @@ The above changes should have minimal impact on your app.
|
|
|
404
548
|
|
|
405
549
|
If you have issues you should verify:
|
|
406
550
|
|
|
407
|
-
|
|
551
|
+
- You're not using any of the removed props.
|
|
408
552
|
|
|
409
553
|
```diff
|
|
410
554
|
useHead({
|
|
@@ -417,7 +561,7 @@ useHead({
|
|
|
417
561
|
})
|
|
418
562
|
```
|
|
419
563
|
|
|
420
|
-
|
|
564
|
+
- If you're using [Template Params](https://unhead.unjs.io/docs/head/guides/plugins/template-params) or [Alias Tag Sorting](https://unhead.unjs.io/docs/head/guides/plugins/alias-sorting), you will need to explicitly opt in to these features now.
|
|
421
565
|
|
|
422
566
|
```ts
|
|
423
567
|
import { AliasSortingPlugin, TemplateParamsPlugin } from '@unhead/vue/plugins'
|
|
@@ -915,9 +1059,9 @@ Finally, providing code serialization functions directly within Nuxt is not idea
|
|
|
915
1059
|
|
|
916
1060
|
We have raised PRs to update modules using EJS syntax, but if you need to do this yourself, you have three backwards/forwards-compatible alternatives:
|
|
917
1061
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1062
|
+
- Moving your string interpolation logic directly into `getContents()`.
|
|
1063
|
+
- Using a custom function to handle the replacement, such as in https://github.com/nuxt-modules/color-mode/pull/240.
|
|
1064
|
+
- Use `es-toolkit/compat` (a drop-in replacement for lodash template), as a dependency of _your_ project rather than Nuxt:
|
|
921
1065
|
|
|
922
1066
|
```diff
|
|
923
1067
|
+ import { readFileSync } from 'node:fs'
|
|
@@ -1000,11 +1144,11 @@ There are two approaches:
|
|
|
1000
1144
|
Nuxt now generates separate TypeScript configurations for different contexts to provide better type-checking experiences:
|
|
1001
1145
|
|
|
1002
1146
|
1. **New TypeScript configuration files**: Nuxt now generates additional TypeScript configurations:
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1147
|
+
- `.nuxt/tsconfig.app.json` - For your app code (Vue components, composables, etc.)
|
|
1148
|
+
- `.nuxt/tsconfig.server.json` - For your server-side code (Nitro/server directory)
|
|
1149
|
+
- `.nuxt/tsconfig.node.json` - For your build-time code (modules, `nuxt.config.ts`, etc.)
|
|
1150
|
+
- `.nuxt/tsconfig.shared.json` - For code shared between app and server contexts (like types and non-environment specific utilities)
|
|
1151
|
+
- `.nuxt/tsconfig.json` - Legacy configuration for backward compatibility
|
|
1008
1152
|
|
|
1009
1153
|
2. **Backward compatibility**: Existing projects that extend `.nuxt/tsconfig.json` will continue to work as before.
|
|
1010
1154
|
|
|
@@ -1033,8 +1177,13 @@ However, to take advantage of improved type checking, you can opt in to the new
|
|
|
1033
1177
|
|
|
1034
1178
|
1. **Update your root `tsconfig.json`** to use project references:
|
|
1035
1179
|
|
|
1180
|
+
::note
|
|
1181
|
+
If your `tsconfig.json` currently has an `"extends": "./.nuxt/tsconfig.json"` line, **remove it** before adding the references. Project references and extends are mutually exclusive.
|
|
1182
|
+
::
|
|
1183
|
+
|
|
1036
1184
|
```json
|
|
1037
1185
|
{
|
|
1186
|
+
// Remove "extends": "./.nuxt/tsconfig.json" if present
|
|
1038
1187
|
"files": [],
|
|
1039
1188
|
"references": [
|
|
1040
1189
|
{ "path": "./.nuxt/tsconfig.app.json" },
|
|
@@ -1055,30 +1204,38 @@ However, to take advantage of improved type checking, you can opt in to the new
|
|
|
1055
1204
|
```
|
|
1056
1205
|
|
|
1057
1206
|
4. **Move all type augmentations into their appropriate context**:
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1207
|
+
- If you are augmenting types for the app context, move the files to the `app/` directory.
|
|
1208
|
+
- If you are augmenting types for the server context, move the files to the `server/` directory.
|
|
1209
|
+
- If you are augmenting types that are **shared between the app and server**, move the files to the `shared/` directory.
|
|
1061
1210
|
|
|
1062
1211
|
::warning
|
|
1063
1212
|
Augmenting types from outside the `app/`, `server/`, or `shared/` directories will not work with the new project references setup.
|
|
1064
1213
|
::
|
|
1065
1214
|
|
|
1066
|
-
5. **Configure
|
|
1215
|
+
5. **Configure TypeScript options** if needed:
|
|
1067
1216
|
<!-- @case-police-ignore tsConfig -->
|
|
1068
1217
|
|
|
1069
1218
|
```ts
|
|
1070
1219
|
export default defineNuxtConfig({
|
|
1071
1220
|
typescript: {
|
|
1072
|
-
//
|
|
1221
|
+
// customize tsconfig.app.json
|
|
1073
1222
|
tsConfig: {
|
|
1074
|
-
|
|
1075
|
-
strict: true,
|
|
1076
|
-
},
|
|
1223
|
+
// ...
|
|
1077
1224
|
},
|
|
1078
|
-
//
|
|
1225
|
+
// customize tsconfig.shared.json
|
|
1226
|
+
sharedTsConfig: {
|
|
1227
|
+
// ...
|
|
1228
|
+
},
|
|
1229
|
+
// customize tsconfig.node.json
|
|
1079
1230
|
nodeTsConfig: {
|
|
1080
|
-
|
|
1081
|
-
|
|
1231
|
+
// ...
|
|
1232
|
+
},
|
|
1233
|
+
},
|
|
1234
|
+
nitro: {
|
|
1235
|
+
typescript: {
|
|
1236
|
+
// customize tsconfig.server.json
|
|
1237
|
+
tsConfig: {
|
|
1238
|
+
// ...
|
|
1082
1239
|
},
|
|
1083
1240
|
},
|
|
1084
1241
|
},
|
|
@@ -1097,11 +1254,11 @@ The new configuration provides better type safety and IntelliSense for projects
|
|
|
1097
1254
|
|
|
1098
1255
|
Four experimental features are no longer configurable in Nuxt 4:
|
|
1099
1256
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1257
|
+
- `experimental.treeshakeClientOnly` will be `true` (default since v3.0)
|
|
1258
|
+
- `experimental.configSchema` will be `true` (default since v3.3)
|
|
1259
|
+
- `experimental.polyfillVueUseHead` will be `false` (default since v3.4)
|
|
1260
|
+
- `experimental.respectNoSSRHeader` will be `false` (default since v3.4)
|
|
1261
|
+
- `vite.devBundler` is no longer configurable - it will use `vite-node` by default
|
|
1105
1262
|
|
|
1106
1263
|
#### Reasons for Change
|
|
1107
1264
|
|
|
@@ -1109,9 +1266,9 @@ These options have been set to their current values for some time and we do not
|
|
|
1109
1266
|
|
|
1110
1267
|
#### Migration Steps
|
|
1111
1268
|
|
|
1112
|
-
|
|
1269
|
+
- `polyfillVueUseHead` is implementable in user-land with [this plugin](https://github.com/nuxt/nuxt/blob/f209158352b09d1986aa320e29ff36353b91c358/packages/nuxt/src/head/runtime/plugins/vueuse-head-polyfill.ts#L10-L11)
|
|
1113
1270
|
|
|
1114
|
-
|
|
1271
|
+
- `respectNoSSRHeader`is implementable in user-land with [server middleware](https://github.com/nuxt/nuxt/blob/c660b39447f0d5b8790c0826092638d321cd6821/packages/nuxt/src/core/runtime/nitro/no-ssr.ts#L8-L9)
|
|
1115
1272
|
|
|
1116
1273
|
### Removal of Top-Level `generate` Configuration
|
|
1117
1274
|
|
|
@@ -1121,8 +1278,8 @@ These options have been set to their current values for some time and we do not
|
|
|
1121
1278
|
|
|
1122
1279
|
The top-level `generate` configuration option is no longer available in Nuxt 4. This includes all of its properties:
|
|
1123
1280
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1281
|
+
- `generate.exclude` - for excluding routes from prerendering
|
|
1282
|
+
- `generate.routes` - for specifying routes to prerender
|
|
1126
1283
|
|
|
1127
1284
|
#### Reasons for Change
|
|
1128
1285
|
|
|
@@ -163,7 +163,7 @@ Read more about the options for `hydrate-on-visible`.
|
|
|
163
163
|
::
|
|
164
164
|
|
|
165
165
|
::note
|
|
166
|
-
Under the hood, this uses Vue's built-in [`hydrateOnVisible` strategy](https://vuejs.org/guide/components/async
|
|
166
|
+
Under the hood, this uses Vue's built-in [`hydrateOnVisible` strategy](https://vuejs.org/guide/components/async#hydrate-on-visible).
|
|
167
167
|
::
|
|
168
168
|
|
|
169
169
|
#### `hydrate-on-idle`
|
|
@@ -181,7 +181,7 @@ You can also pass a number which serves as a max timeout.
|
|
|
181
181
|
```
|
|
182
182
|
|
|
183
183
|
::note
|
|
184
|
-
Under the hood, this uses Vue's built-in [`hydrateOnIdle` strategy](https://vuejs.org/guide/components/async
|
|
184
|
+
Under the hood, this uses Vue's built-in [`hydrateOnIdle` strategy](https://vuejs.org/guide/components/async#hydrate-on-idle).
|
|
185
185
|
::
|
|
186
186
|
|
|
187
187
|
#### `hydrate-on-interaction`
|
|
@@ -199,7 +199,7 @@ Hydrates the component after a specified interaction (e.g., click, mouseover).
|
|
|
199
199
|
If you do not pass an event or list of events, it defaults to hydrating on `pointerenter`, `click` and `focus`.
|
|
200
200
|
|
|
201
201
|
::note
|
|
202
|
-
Under the hood, this uses Vue's built-in [`hydrateOnInteraction` strategy](https://vuejs.org/guide/components/async
|
|
202
|
+
Under the hood, this uses Vue's built-in [`hydrateOnInteraction` strategy](https://vuejs.org/guide/components/async#hydrate-on-interaction).
|
|
203
203
|
::
|
|
204
204
|
|
|
205
205
|
#### `hydrate-on-media-query`
|
|
@@ -215,7 +215,7 @@ Hydrates the component when the window matches a media query.
|
|
|
215
215
|
```
|
|
216
216
|
|
|
217
217
|
::note
|
|
218
|
-
Under the hood, this uses Vue's built-in [`hydrateOnMediaQuery` strategy](https://vuejs.org/guide/components/async
|
|
218
|
+
Under the hood, this uses Vue's built-in [`hydrateOnMediaQuery` strategy](https://vuejs.org/guide/components/async#hydrate-on-media-query).
|
|
219
219
|
::
|
|
220
220
|
|
|
221
221
|
#### `hydrate-after`
|
|
@@ -71,7 +71,7 @@ export const useFoo = () => {
|
|
|
71
71
|
|
|
72
72
|
### Access plugin injections
|
|
73
73
|
|
|
74
|
-
You can access [plugin injections](/docs/4.x/guide/directory-structure/plugins#providing-helpers) from composables:
|
|
74
|
+
You can access [plugin injections](/docs/4.x/guide/directory-structure/app/plugins#providing-helpers) from composables:
|
|
75
75
|
|
|
76
76
|
```ts [app/composables/test.ts]
|
|
77
77
|
export const useHello = () => {
|
|
@@ -11,7 +11,7 @@ For best performance, components placed in this directory will be automatically
|
|
|
11
11
|
|
|
12
12
|
## Enable Layouts
|
|
13
13
|
|
|
14
|
-
Layouts are enabled by adding [`<NuxtLayout>`](/docs/4.x/api/components/nuxt-layout) to your [`app.vue`](/docs/4.x/guide/directory-structure/app):
|
|
14
|
+
Layouts are enabled by adding [`<NuxtLayout>`](/docs/4.x/api/components/nuxt-layout) to your [`app.vue`](/docs/4.x/guide/directory-structure/app/app):
|
|
15
15
|
|
|
16
16
|
```vue [app/app.vue]
|
|
17
17
|
<template>
|
|
@@ -34,7 +34,7 @@ If no layout is specified, `app/layouts/default.vue` will be used.
|
|
|
34
34
|
::
|
|
35
35
|
|
|
36
36
|
::important
|
|
37
|
-
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/4.x/guide/directory-structure/app) instead.
|
|
37
|
+
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/4.x/guide/directory-structure/app/app) instead.
|
|
38
38
|
::
|
|
39
39
|
|
|
40
40
|
::important
|
|
@@ -48,13 +48,13 @@ Nuxt provides two globally available helpers that can be returned directly from
|
|
|
48
48
|
1. [`navigateTo`](/docs/4.x/api/utils/navigate-to) - Redirects to the given route
|
|
49
49
|
2. [`abortNavigation`](/docs/4.x/api/utils/abort-navigation) - Aborts the navigation, with an optional error message.
|
|
50
50
|
|
|
51
|
-
Unlike [navigation guards](https://router.vuejs.org/guide/advanced/navigation-guards
|
|
51
|
+
Unlike [navigation guards](https://router.vuejs.org/guide/advanced/navigation-guards#Global-Before-Guards) from `vue-router`, a third `next()` argument is not passed, and **redirect or route cancellation is handled by returning a value from the middleware**.
|
|
52
52
|
|
|
53
53
|
Possible return values are:
|
|
54
54
|
|
|
55
55
|
* nothing (a simple `return` or no return at all) - does not block navigation and will move to the next middleware function, if any, or complete the route navigation
|
|
56
|
-
* `return navigateTo('/')` - redirects to the given path and will set the redirect code to [`302` Found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302) if the redirect happens on the server side
|
|
57
|
-
* `return navigateTo('/', { redirectCode: 301 })` - redirects to the given path and will set the redirect code to [`301` Moved Permanently](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301) if the redirect happens on the server side
|
|
56
|
+
* `return navigateTo('/')` - redirects to the given path and will set the redirect code to [`302` Found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/302) if the redirect happens on the server side
|
|
57
|
+
* `return navigateTo('/', { redirectCode: 301 })` - redirects to the given path and will set the redirect code to [`301` Moved Permanently](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/301) if the redirect happens on the server side
|
|
58
58
|
* `return abortNavigation()` - stops the current navigation
|
|
59
59
|
* `return abortNavigation(error)` - rejects the current navigation with an error
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ Possible return values are:
|
|
|
62
62
|
:read-more{to="/docs/4.x/api/utils/abort-navigation"}
|
|
63
63
|
|
|
64
64
|
::important
|
|
65
|
-
We recommend using the helper functions above for performing redirects or stopping navigation. Other possible return values described in [the vue-router docs](https://router.vuejs.org/guide/advanced/navigation-guards
|
|
65
|
+
We recommend using the helper functions above for performing redirects or stopping navigation. Other possible return values described in [the vue-router docs](https://router.vuejs.org/guide/advanced/navigation-guards#Global-Before-Guards) may work but there may be breaking changes in future.
|
|
66
66
|
::
|
|
67
67
|
|
|
68
68
|
## Middleware Order
|
|
@@ -6,12 +6,12 @@ navigation.icon: i-vscode-icons-folder-type-view
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
::note
|
|
9
|
-
To reduce your application's bundle size, this directory is **optional**, meaning that [`vue-router`](https://router.vuejs.org) won't be included if you only use [`app.vue`](/docs/4.x/guide/directory-structure/app). To force the pages system, set `pages: true` in `nuxt.config` or have a [`router.options.ts`](/docs/4.x/guide/recipes/custom-routing#using-routeroptions).
|
|
9
|
+
To reduce your application's bundle size, this directory is **optional**, meaning that [`vue-router`](https://router.vuejs.org) won't be included if you only use [`app.vue`](/docs/4.x/guide/directory-structure/app/app). To force the pages system, set `pages: true` in `nuxt.config` or have a [`router.options.ts`](/docs/4.x/guide/recipes/custom-routing#using-routeroptions).
|
|
10
10
|
::
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
14
|
-
Pages are Vue components and can have any [valid extension](/docs/4.x/api/
|
|
14
|
+
Pages are Vue components and can have any [valid extension](/docs/4.x/api/nuxt-config#extensions) that Nuxt supports (by default `.vue`, `.js`, `.jsx`, `.mjs`, `.ts` or `.tsx`).
|
|
15
15
|
|
|
16
16
|
Nuxt will automatically create a route for every page in your `~/pages/` directory.
|
|
17
17
|
|
|
@@ -46,7 +46,7 @@ export default defineComponent({
|
|
|
46
46
|
|
|
47
47
|
The `app/pages/index.vue` file will be mapped to the `/` route of your application.
|
|
48
48
|
|
|
49
|
-
If you are using [`app.vue`](/docs/4.x/guide/directory-structure/app), make sure to use the [`<NuxtPage/>`](/docs/4.x/api/components/nuxt-page) component to display the current page:
|
|
49
|
+
If you are using [`app.vue`](/docs/4.x/guide/directory-structure/app/app), make sure to use the [`<NuxtPage/>`](/docs/4.x/api/components/nuxt-page) component to display the current page:
|
|
50
50
|
|
|
51
51
|
```vue [app/app.vue]
|
|
52
52
|
<template>
|
|
@@ -93,7 +93,7 @@ Here are some examples to illustrate what a page with a single root element look
|
|
|
93
93
|
|
|
94
94
|
## Dynamic Routes
|
|
95
95
|
|
|
96
|
-
If you place anything within square brackets, it will be turned into a [dynamic route](https://router.vuejs.org/guide/essentials/dynamic-matching
|
|
96
|
+
If you place anything within square brackets, it will be turned into a [dynamic route](https://router.vuejs.org/guide/essentials/dynamic-matching) parameter. You can mix and match multiple parameters and even non-dynamic text within a file name or directory.
|
|
97
97
|
|
|
98
98
|
If you want a parameter to be _optional_, you must enclose it in double square brackets - for example, `~/pages/[[slug]]/index.vue` or `~/pages/[[slug]].vue` will match both `/` and `/test`.
|
|
99
99
|
|
|
@@ -154,7 +154,7 @@ Navigating to `/hello/world` would render:
|
|
|
154
154
|
|
|
155
155
|
## Nested Routes
|
|
156
156
|
|
|
157
|
-
It is possible to display [nested routes](https://
|
|
157
|
+
It is possible to display [nested routes](https://router.vuejs.org/guide/essentials/nested-routes) with `<NuxtPage>`.
|
|
158
158
|
|
|
159
159
|
Example:
|
|
160
160
|
|
|
@@ -268,9 +268,9 @@ console.log(route.meta.title) // My home page
|
|
|
268
268
|
</script>
|
|
269
269
|
```
|
|
270
270
|
|
|
271
|
-
If you are using nested routes, the page metadata from all these routes will be merged into a single object. For more on route meta, see the [vue-router docs](https://router.vuejs.org/guide/advanced/meta
|
|
271
|
+
If you are using nested routes, the page metadata from all these routes will be merged into a single object. For more on route meta, see the [vue-router docs](https://router.vuejs.org/guide/advanced/meta).
|
|
272
272
|
|
|
273
|
-
Much like `defineEmits` or `defineProps` (see [Vue docs](https://vuejs.org/api/sfc-script-setup
|
|
273
|
+
Much like `defineEmits` or `defineProps` (see [Vue docs](https://vuejs.org/api/sfc-script-setup#defineprops-defineemits)), `definePageMeta` is a **compiler macro**. It will be compiled away so you cannot reference it within your component. Instead, the metadata passed to it will be hoisted out of the component.
|
|
274
274
|
Therefore, the page meta object cannot reference the component. However, it can reference imported bindings, as well as locally defined **pure functions**.
|
|
275
275
|
|
|
276
276
|
::warning
|
|
@@ -301,13 +301,13 @@ Of course, you are welcome to define metadata for your own use throughout your a
|
|
|
301
301
|
|
|
302
302
|
#### `alias`
|
|
303
303
|
|
|
304
|
-
You can define page aliases. They allow you to access the same page from different paths. It can be either a string or an array of strings as defined [in the vue-router documentation](https://router.vuejs.org/guide/essentials/redirect-and-alias
|
|
304
|
+
You can define page aliases. They allow you to access the same page from different paths. It can be either a string or an array of strings as defined [in the vue-router documentation](https://router.vuejs.org/guide/essentials/redirect-and-alias#Alias).
|
|
305
305
|
|
|
306
306
|
#### `keepalive`
|
|
307
307
|
|
|
308
|
-
Nuxt will automatically wrap your page in [the Vue `<KeepAlive>` component](https://vuejs.org/guide/built-ins/keep-alive
|
|
308
|
+
Nuxt will automatically wrap your page in [the Vue `<KeepAlive>` component](https://vuejs.org/guide/built-ins/keep-alive#keepalive) if you set `keepalive: true` in your `definePageMeta`. This might be useful to do, for example, in a parent route that has dynamic child routes, if you want to preserve page state across route changes.
|
|
309
309
|
|
|
310
|
-
When your goal is to preserve state for parent routes use this syntax: `<NuxtPage keepalive />`. You can also set props to be passed to `<KeepAlive>` (see [a full list](https://vuejs.org/api/built-in-components
|
|
310
|
+
When your goal is to preserve state for parent routes use this syntax: `<NuxtPage keepalive />`. You can also set props to be passed to `<KeepAlive>` (see [a full list](https://vuejs.org/api/built-in-components#keepalive)).
|
|
311
311
|
|
|
312
312
|
You can set a default value for this property [in your `nuxt.config`](/docs/4.x/api/nuxt-config#keepalive).
|
|
313
313
|
|
|
@@ -321,13 +321,13 @@ You can define the layout used to render the route. This can be either false (to
|
|
|
321
321
|
|
|
322
322
|
#### `layoutTransition` and `pageTransition`
|
|
323
323
|
|
|
324
|
-
You can define transition properties for the `<transition>` component that wraps your pages and layouts, or pass `false` to disable the `<transition>` wrapper for that route. You can see [a list of options that can be passed](https://vuejs.org/api/built-in-components
|
|
324
|
+
You can define transition properties for the `<transition>` component that wraps your pages and layouts, or pass `false` to disable the `<transition>` wrapper for that route. You can see [a list of options that can be passed](https://vuejs.org/api/built-in-components#transition) or read [more about how transitions work](https://vuejs.org/guide/built-ins/transition#transition).
|
|
325
325
|
|
|
326
326
|
You can set default values for these properties [in your `nuxt.config`](/docs/4.x/api/nuxt-config#layouttransition).
|
|
327
327
|
|
|
328
328
|
#### `middleware`
|
|
329
329
|
|
|
330
|
-
You can define middleware to apply before loading this page. It will be merged with all the other middleware used in any matching parent/child routes. It can be a string, a function (an anonymous/inlined middleware function following [the global before guard pattern](https://router.vuejs.org/guide/advanced/navigation-guards
|
|
330
|
+
You can define middleware to apply before loading this page. It will be merged with all the other middleware used in any matching parent/child routes. It can be a string, a function (an anonymous/inlined middleware function following [the global before guard pattern](https://router.vuejs.org/guide/advanced/navigation-guards#Global-Before-Guards)), or an array of strings/functions. [More about named middleware](/docs/4.x/guide/directory-structure/app/middleware).
|
|
331
331
|
|
|
332
332
|
#### `name`
|
|
333
333
|
|
|
@@ -335,7 +335,7 @@ You may define a name for this page's route.
|
|
|
335
335
|
|
|
336
336
|
#### `path`
|
|
337
337
|
|
|
338
|
-
You may define a path matcher, if you have a more complex pattern than can be expressed with the file name. See [the `vue-router` docs](https://router.vuejs.org/guide/essentials/route-matching-syntax
|
|
338
|
+
You may define a path matcher, if you have a more complex pattern than can be expressed with the file name. See [the `vue-router` docs](https://router.vuejs.org/guide/essentials/route-matching-syntax#Custom-regex-in-params) for more information.
|
|
339
339
|
|
|
340
340
|
#### `props`
|
|
341
341
|
|
|
@@ -205,7 +205,7 @@ Note that we highly recommend using [`composables`](/docs/4.x/guide/directory-st
|
|
|
205
205
|
|
|
206
206
|
::warning
|
|
207
207
|
**If your plugin provides a `ref` or `computed`, it will not be unwrapped in a component `<template>`.** :br
|
|
208
|
-
This is due to how Vue works with refs that aren't top-level to the template. You can read more about it [in the Vue documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals
|
|
208
|
+
This is due to how Vue works with refs that aren't top-level to the template. You can read more about it [in the Vue documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals#caveat-when-unwrapping-in-templates).
|
|
209
209
|
::
|
|
210
210
|
|
|
211
211
|
## Typing Plugins
|
|
@@ -234,10 +234,6 @@ declare module 'vue' {
|
|
|
234
234
|
export {}
|
|
235
235
|
```
|
|
236
236
|
|
|
237
|
-
::note
|
|
238
|
-
If you are using WebStorm, you may need to augment `@vue/runtime-core` until [this issue](https://youtrack.jetbrains.com/issue/WEB-59818/VUE-TypeScript-WS-PS-does-not-correctly-display-type-of-globally-injected-properties) is resolved.
|
|
239
|
-
::
|
|
240
|
-
|
|
241
237
|
## Vue Plugins
|
|
242
238
|
|
|
243
239
|
If you want to use Vue plugins, like [vue-gtag](https://github.com/MatteoGabriele/vue-gtag) to add Google Analytics tags, you can use a Nuxt plugin to do so.
|
|
@@ -5,7 +5,7 @@ head.title: "node_modules/"
|
|
|
5
5
|
navigation.icon: i-vscode-icons-folder-type-node
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
The package manager ([`npm`](https://docs.npmjs.com/cli/commands/npm) or [`yarn`](https://yarnpkg.com) or [`pnpm`](https://pnpm.io/cli/install) or [`bun`](https://bun.
|
|
8
|
+
The package manager ([`npm`](https://docs.npmjs.com/cli/commands/npm/) or [`yarn`](https://yarnpkg.com) or [`pnpm`](https://pnpm.io/cli/install) or [`bun`](https://bun.com/package-manager)) creates this directory to store the dependencies of your project.
|
|
9
9
|
|
|
10
10
|
::important
|
|
11
11
|
This directory should be added to your [`.gitignore`](/docs/4.x/guide/directory-structure/gitignore) file to avoid pushing the dependencies to your repository.
|
|
@@ -22,6 +22,6 @@ useSeoMeta({
|
|
|
22
22
|
</script>
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
::tip{to="https://v2.nuxt.com/docs/directory-structure/static" target="_blank"}
|
|
25
|
+
::tip{to="https://v2.nuxt.com/docs/directory-structure/static/" target="_blank"}
|
|
26
26
|
This is known as the [`static/`] directory in Nuxt 2.
|
|
27
27
|
::
|
|
@@ -132,9 +132,9 @@ export const defineWrappedResponseHandler = <T extends EventHandlerRequest, D> (
|
|
|
132
132
|
|
|
133
133
|
## Server Types
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
Auto-imports and other types are different for the `server/` directory, as it is running in a different context from the `app/` directory.
|
|
136
|
+
|
|
137
|
+
By default, Nuxt 4 generates a [`tsconfig.json`](/docs/4.x/guide/directory-structure/tsconfig) which includes a project reference covering the `server/` folder which ensures accurate typings.
|
|
138
138
|
|
|
139
139
|
## Recipes
|
|
140
140
|
|
|
@@ -158,7 +158,7 @@ You can now universally call this API on `/api/hello/nuxt` and get `Hello, nuxt!
|
|
|
158
158
|
|
|
159
159
|
### Matching HTTP Method
|
|
160
160
|
|
|
161
|
-
Handle file names can be suffixed with `.get`, `.post`, `.put`, `.delete`, ... to match request's [HTTP Method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).
|
|
161
|
+
Handle file names can be suffixed with `.get`, `.post`, `.put`, `.delete`, ... to match request's [HTTP Method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods).
|
|
162
162
|
|
|
163
163
|
```ts [server/api/test.get.ts]
|
|
164
164
|
export default defineEventHandler(() => 'Test get handler')
|
|
@@ -226,7 +226,7 @@ export default defineEventHandler(async (event) => {
|
|
|
226
226
|
})
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
-
::tip{to="https://unjs.io/blog/2023-08-15-h3-towards-the-edge-of-the-web
|
|
229
|
+
::tip{to="https://unjs.io/blog/2023-08-15-h3-towards-the-edge-of-the-web/#runtime-type-safe-request-utils"}
|
|
230
230
|
Alternatively, use `readValidatedBody` with a schema validator such as Zod for runtime and type safety.
|
|
231
231
|
::
|
|
232
232
|
|