@nuxt/docs 4.1.3 → 4.2.0

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.
@@ -28,7 +28,7 @@ Or follow the steps below to set up a new Nuxt project on your computer.
28
28
  ::note
29
29
  ::details
30
30
  :summary[Additional notes for an optimal setup:]
31
- - **Node.js**: Make sure to use an even numbered version (18, 20, etc)
31
+ - **Node.js**: Make sure to use an even numbered version (20, 22, etc.)
32
32
  - **Nuxtr**: Install the community-developed [Nuxtr extension](https://marketplace.visualstudio.com/items?itemName=Nuxtr.nuxtr-vscode)
33
33
  - **WSL**: If you are using Windows and experience slow HMR, you may want to try using [WSL (Windows Subsystem for Linux)](https://docs.microsoft.com/en-us/windows/wsl/install) which may solve some performance issues.
34
34
  - **Windows slow DNS resolution** - instead of using `localhost:3000` for local dev server on Windows, use `127.0.0.1` for much faster loading experience on browsers.
@@ -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](#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](#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.
@@ -81,19 +221,23 @@ You can run all the codemods mentioned in this guide using the following `codemo
81
221
  ::code-group
82
222
 
83
223
  ```bash [npm]
84
- npx codemod@latest nuxt/4/migration-recipe
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
- yarn dlx codemod@latest nuxt/4/migration-recipe
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
- pnpm dlx codemod@latest nuxt/4/migration-recipe
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
- bun x codemod@latest nuxt/4/migration-recipe
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
- * the new Nuxt default `srcDir` is `app/` by default, and most things are resolved from there.
114
- * `serverDir` now defaults to `<rootDir>/server` rather than `<srcDir>/server`
115
- * `layers/`, `modules/` and `public/` are resolved relative to `<rootDir>` by default
116
- * if using [Nuxt Content v2.13+](https://github.com/nuxt/content/pull/2649), `content/` is resolved relative to `<rootDir>`
117
- * 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>/`
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
- * Modules defined in the `modules` array in `nuxt.config.ts`
283
- * Auto-discovered modules from the `modules/` directory
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
- * Extended layers have lower priority than the consuming project
289
- * Module execution order matches the intuitive layer inheritance pattern
290
- * Module configuration and hooks work as expected in multi-layer setups
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
- * Removed props: `vmid`, `hid`, `children`, `body`.
398
- * Promise input no longer supported.
399
- * Tags are now sorted using Capo.js by default.
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
- * You're not using any of the removed props.
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
- * 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.
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
- * Moving your string interpolation logic directly into `getContents()`.
919
- * Using a custom function to handle the replacement, such as in https://github.com/nuxt-modules/color-mode/pull/240.
920
- * Use `es-toolkit/compat` (a drop-in replacement for lodash template), as a dependency of _your_ project rather than Nuxt:
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
- * `.nuxt/tsconfig.app.json` - For your app code (Vue components, composables, etc.)
1004
- * `.nuxt/tsconfig.server.json` - For your server-side code (Nitro/server directory)
1005
- * `.nuxt/tsconfig.node.json` - For your build-time code (modules, `nuxt.config.ts`, etc.)
1006
- * `.nuxt/tsconfig.shared.json` - For code shared between app and server contexts (like types and non-environment specific utilities)
1007
- * `.nuxt/tsconfig.json` - Legacy configuration for backward compatibility
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,9 +1204,9 @@ 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
- * If you are augmenting types for the app context, move the files to the `app/` directory.
1059
- * If you are augmenting types for the server context, move the files to the `server/` directory.
1060
- * If you are augmenting types that are **shared between the app and server**, move the files to the `shared/` directory.
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.
@@ -1097,11 +1246,11 @@ The new configuration provides better type safety and IntelliSense for projects
1097
1246
 
1098
1247
  Four experimental features are no longer configurable in Nuxt 4:
1099
1248
 
1100
- * `experimental.treeshakeClientOnly` will be `true` (default since v3.0)
1101
- * `experimental.configSchema` will be `true` (default since v3.3)
1102
- * `experimental.polyfillVueUseHead` will be `false` (default since v3.4)
1103
- * `experimental.respectNoSSRHeader` will be `false` (default since v3.4)
1104
- * `vite.devBundler` is no longer configurable - it will use `vite-node` by default
1249
+ - `experimental.treeshakeClientOnly` will be `true` (default since v3.0)
1250
+ - `experimental.configSchema` will be `true` (default since v3.3)
1251
+ - `experimental.polyfillVueUseHead` will be `false` (default since v3.4)
1252
+ - `experimental.respectNoSSRHeader` will be `false` (default since v3.4)
1253
+ - `vite.devBundler` is no longer configurable - it will use `vite-node` by default
1105
1254
 
1106
1255
  #### Reasons for Change
1107
1256
 
@@ -1109,9 +1258,9 @@ These options have been set to their current values for some time and we do not
1109
1258
 
1110
1259
  #### Migration Steps
1111
1260
 
1112
- * `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)
1261
+ - `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
1262
 
1114
- * `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)
1263
+ - `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
1264
 
1116
1265
  ### Removal of Top-Level `generate` Configuration
1117
1266
 
@@ -1121,8 +1270,8 @@ These options have been set to their current values for some time and we do not
1121
1270
 
1122
1271
  The top-level `generate` configuration option is no longer available in Nuxt 4. This includes all of its properties:
1123
1272
 
1124
- * `generate.exclude` - for excluding routes from prerendering
1125
- * `generate.routes` - for specifying routes to prerender
1273
+ - `generate.exclude` - for excluding routes from prerendering
1274
+ - `generate.routes` - for specifying routes to prerender
1126
1275
 
1127
1276
  #### Reasons for Change
1128
1277
 
@@ -50,6 +50,10 @@ When adding modules to your package, things were a little different. A sample li
50
50
 
51
51
  So in Nuxt 2, the bundler (webpack) would pull in the CJS file ('main') for the server build and use the ESM file ('module') for the client build.
52
52
 
53
+ ::note
54
+ The `module` field is a convention used by bundlers like webpack and Rollup, but is not recognized by Node.js itself. Node.js only uses the [`exports`](https://nodejs.org/api/packages.html#exports) and [`main`](https://nodejs.org/api/packages.html#main) fields for module resolution.
55
+ ::
56
+
53
57
  However, in recent Node.js LTS releases, it is now possible to [use native ESM module](https://nodejs.org/api/esm.html) within Node.js. That means that Node.js itself can process JavaScript using ESM syntax, although it doesn't do it by default. The two most common ways to enable ESM syntax are:
54
58
 
55
59
  - set `"type": "module"` within your `package.json` and keep using `.js` extension
@@ -59,7 +63,7 @@ This is what we do for Nuxt Nitro; we output a `.output/server/index.mjs` file.
59
63
 
60
64
  ### What Are Valid Imports in a Node.js Context?
61
65
 
62
- When you `import` a module rather than `require` it, Node.js resolves it differently. For example, when you import `sample-library`, Node.js will look not for the `main` but for the `exports` or `module` entry in that library's `package.json`.
66
+ When you `import` a module rather than `require` it, Node.js resolves it differently. For example, when you import `sample-library`, Node.js will look for the `exports` entry in that library's `package.json`, or fall back to the `main` entry if `exports` is not defined.
63
67
 
64
68
  This is also true of dynamic imports, like `const b = await import('sample-library')`.
65
69
 
@@ -87,6 +87,44 @@ export default defineNuxtConfig({
87
87
  This feature will likely be removed in a near future.
88
88
  ::
89
89
 
90
+ ## extractAsyncDataHandlers
91
+
92
+ Extracts handler functions from `useAsyncData` and `useLazyAsyncData` calls into separate chunks for improved code splitting and caching efficiency.
93
+
94
+ ```ts twoslash [nuxt.config.ts]
95
+ export default defineNuxtConfig({
96
+ experimental: {
97
+ extractAsyncDataHandlers: true,
98
+ },
99
+ })
100
+ ```
101
+
102
+ This feature transforms inline handler functions into dynamically imported chunks:
103
+
104
+ ```vue
105
+ <!-- Before -->
106
+ <script setup>
107
+ const { data } = await useAsyncData('user', async () => {
108
+ return await $fetch('/api/user')
109
+ })
110
+ </script>
111
+ ```
112
+
113
+ ```vue
114
+ <!-- After transformation -->
115
+ <script setup>
116
+ const { data } = await useAsyncData('user', () =>
117
+ import('/generated-chunk.js').then(r => r.default()),
118
+ )
119
+ </script>
120
+ ```
121
+
122
+ The benefit of this transformation is that we can split out data fetching logic &mdash; while still allowing the code to be loaded if required.
123
+
124
+ ::important
125
+ This feature is only recommended for **static builds** with payload extraction, and where data does not need to be re-fetched at runtime.
126
+ ::
127
+
90
128
  ## emitRouteChunkError
91
129
 
92
130
  Emits `app:chunkError` hook when there is an error loading vite/webpack chunks. Default behavior is to perform a reload of the new route on navigation to a new route when a chunk fails to load.
@@ -831,3 +869,53 @@ export default defineNuxtConfig({
831
869
  },
832
870
  })
833
871
  ```
872
+
873
+ ## typescriptPlugin
874
+
875
+ Enable enhanced TypeScript developer experience with the `@dxup/nuxt` module.
876
+
877
+ This experimental plugin provides improved TypeScript integration and development tooling for better DX when working with TypeScript in Nuxt applications.
878
+
879
+ This flag is disabled by default, but you can enable this feature:
880
+
881
+ ```ts twoslash [nuxt.config.ts]
882
+ export default defineNuxtConfig({
883
+ experimental: {
884
+ typescriptPlugin: true,
885
+ },
886
+ })
887
+ ```
888
+
889
+ ::important
890
+ To use this feature, you need to:
891
+ - Have `typescript` installed as a dependency
892
+ - Configure VS Code to use your workspace TypeScript version (see [VS Code documentation](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript))
893
+ ::
894
+
895
+ ::read-more{icon="i-simple-icons-github" to="https://github.com/KazariEX/dxup" target="_blank"}
896
+ Learn more about **@dxup/nuxt**.
897
+ ::
898
+
899
+ ## viteEnvironmentApi
900
+
901
+ Enable Vite 6's new [Environment API](https://vite.dev/guide/api-environment) for improved build configuration and plugin architecture.
902
+
903
+ When you set `future.compatibilityVersion` to `5`, this feature is enabled by default. You can also enable it explicitly for testing:
904
+
905
+ ```ts twoslash [nuxt.config.ts]
906
+ export default defineNuxtConfig({
907
+ experimental: {
908
+ viteEnvironmentApi: true,
909
+ },
910
+ })
911
+ ```
912
+
913
+ The Vite Environment API provides better consistency between development and production builds, more granular control over environment-specific configuration, and improved performance.
914
+
915
+ ::important
916
+ Enabling this feature changes how Vite plugins are registered and configured. See the [Vite Environment API migration guide](/docs/4.x/getting-started/upgrade#migration-to-vite-environment-api) for details on updating your plugins.
917
+ ::
918
+
919
+ ::read-more{to="https://vite.dev/guide/api-environment" target="_blank"}
920
+ Learn more about Vite's Environment API.
921
+ ::
@@ -61,9 +61,21 @@ There is also a `future` namespace for early opting-in to new features that will
61
61
 
62
62
  ### compatibilityVersion
63
63
 
64
- This is used for enabling early access to Nuxt features or flags.
64
+ This enables early access to Nuxt features or flags.
65
65
 
66
- It is not configurable yet in Nuxt 4, but once we begin merging breaking changes for v5, it will be possible to enable it.
66
+ Setting `compatibilityVersion` to `5` changes defaults throughout your Nuxt configuration to opt in to Nuxt v5 behaviour, including enabling the [Vite Environment API](/docs/4.x/guide/going-further/experimental-features#viteenvironmentapi).
67
+
68
+ ```ts
69
+ export default defineNuxtConfig({
70
+ future: {
71
+ compatibilityVersion: 5,
72
+ },
73
+ })
74
+ ```
75
+
76
+ ::read-more{to="/docs/4.x/getting-started/upgrade#testing-nuxt-5"}
77
+ Learn more about testing Nuxt 5.
78
+ ::
67
79
 
68
80
  ### multiApp
69
81
 
@@ -501,35 +501,51 @@ export default defineNuxtModule({
501
501
 
502
502
  #### Using Other Modules in Your Module
503
503
 
504
- If your module depends on other modules, you can add them by using Nuxt Kit's `installModule` utility. For example, if you wanted to use Nuxt Tailwind in your module, you could add it as below:
504
+ If your module depends on other modules, you can specify them using the `moduleDependencies` option. This provides a more robust way to handle module dependencies with version constraints and configuration merging:
505
505
 
506
506
  ```ts
507
- import { createResolver, defineNuxtModule, installModule } from '@nuxt/kit'
508
-
509
- export default defineNuxtModule<ModuleOptions>({
510
- async setup (options, nuxt) {
511
- const resolver = createResolver(import.meta.url)
507
+ import { createResolver, defineNuxtModule } from '@nuxt/kit'
512
508
 
513
- // We can inject our CSS file which includes Tailwind's directives
514
- nuxt.options.css.push(resolver.resolve('./runtime/assets/styles.css'))
509
+ const resolver = createResolver(import.meta.url)
515
510
 
516
- await installModule('@nuxtjs/tailwindcss', {
517
- // module configuration
518
- exposeConfig: true,
519
- config: {
520
- darkMode: 'class',
521
- content: {
522
- files: [
523
- resolver.resolve('./runtime/components/**/*.{vue,mjs,ts}'),
524
- resolver.resolve('./runtime/*.{mjs,js,ts}'),
525
- ],
511
+ export default defineNuxtModule<ModuleOptions>({
512
+ meta: {
513
+ name: 'my-module',
514
+ },
515
+ moduleDependencies: {
516
+ '@nuxtjs/tailwindcss': {
517
+ // You can specify a version constraint for the module
518
+ version: '>=6',
519
+ // Any configuration that should override `nuxt.options`
520
+ overrides: {
521
+ exposeConfig: true,
522
+ },
523
+ // Any configuration that should be set. It will override module defaults but
524
+ // will not override any configuration set in `nuxt.options`
525
+ defaults: {
526
+ config: {
527
+ darkMode: 'class',
528
+ content: {
529
+ files: [
530
+ resolver.resolve('./runtime/components/**/*.{vue,mjs,ts}'),
531
+ resolver.resolve('./runtime/*.{mjs,js,ts}'),
532
+ ],
533
+ },
526
534
  },
527
535
  },
528
- })
536
+ },
537
+ },
538
+ setup (options, nuxt) {
539
+ // We can inject our CSS file which includes Tailwind's directives
540
+ nuxt.options.css.push(resolver.resolve('./runtime/assets/styles.css'))
529
541
  },
530
542
  })
531
543
  ```
532
544
 
545
+ ::callout{type="info"}
546
+ The `moduleDependencies` option replaces the deprecated `installModule` function and ensures proper setup order and configuration merging.
547
+ ::
548
+
533
549
  #### Using Hooks
534
550
 
535
551
  [Lifecycle hooks](/docs/4.x/guide/going-further/hooks) allow you to expand almost every aspect of Nuxt. Modules can hook to them programmatically or through the `hooks` map in their definition.
@@ -234,22 +234,30 @@ export default defineNuxtConfig({
234
234
 
235
235
  ## Multi-Layer Support for Nuxt Modules
236
236
 
237
- You can use the internal array `nuxt.options._layers` to support custom multi-layer handling for your modules.
237
+ You can use the [`getLayerDirectories`](/docs/4.x/api/kit/layers#getlayerdirectories) utility from Nuxt Kit to support custom multi-layer handling for your modules.
238
238
 
239
239
  ```ts [modules/my-module.ts]
240
+ import { defineNuxtModule, getLayerDirectories } from 'nuxt/kit'
241
+
240
242
  export default defineNuxtModule({
241
243
  setup (_options, nuxt) {
242
- for (const layer of nuxt.options._layers) {
243
- // You can check for a custom directory existence to extend for each layer
244
- console.log('Custom extension for', layer.cwd, layer.config)
244
+ const layerDirs = getLayerDirectories()
245
+
246
+ for (const [index, layer] of layerDirs.entries()) {
247
+ console.log(`Layer ${index}:`)
248
+ console.log(` Root: ${layer.root}`)
249
+ console.log(` App: ${layer.app}`)
250
+ console.log(` Server: ${layer.server}`)
251
+ console.log(` Pages: ${layer.appPages}`)
252
+ // ... other directories
245
253
  }
246
254
  },
247
255
  })
248
256
  ```
249
257
 
250
258
  **Notes:**
251
- - Earlier items in the `_layers` array have higher priority and override later ones
252
- - The user's project is the first item in the `_layers` array
259
+ - Earlier items in the array have higher priority and override later ones
260
+ - The user's project is the first item in the array
253
261
 
254
262
  ## Going Deeper
255
263
 
@@ -63,3 +63,44 @@ import config from '~/data/hello.yaml'
63
63
  ```
64
64
 
65
65
  ::
66
+
67
+ ## Using Vite Plugins in Nuxt Modules
68
+
69
+ If you're developing a Nuxt module and need to add Vite plugins, you should use the [`addVitePlugin`](/docs/4.x/api/kit/builder#addviteplugin) utility:
70
+
71
+ ```ts [modules/my-module.ts]
72
+ import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
73
+ import yaml from '@rollup/plugin-yaml'
74
+
75
+ export default defineNuxtModule({
76
+ setup () {
77
+ addVitePlugin(yaml())
78
+ },
79
+ })
80
+ ```
81
+
82
+ For environment-specific plugins in Nuxt 5+, use the `applyToEnvironment()` method:
83
+
84
+ ```ts [modules/my-module.ts]
85
+ import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
86
+
87
+ export default defineNuxtModule({
88
+ setup () {
89
+ addVitePlugin(() => ({
90
+ name: 'my-client-plugin',
91
+ applyToEnvironment (environment) {
92
+ return environment.name === 'client'
93
+ },
94
+ // Plugin configuration
95
+ }))
96
+ },
97
+ })
98
+ ```
99
+
100
+ ::important
101
+ If you're writing code that needs to access resolved Vite configuration, you should use the `config` and `configResolved` hooks _within_ your Vite plugin, rather than using Nuxt's `vite:extend`, `vite:extendConfig` and `vite:configResolved`.
102
+ ::
103
+
104
+ ::read-more{to="/docs/4.x/api/kit/builder#addviteplugin"}
105
+ Read more about `addVitePlugin` in the Nuxt Kit documentation.
106
+ ::
@@ -104,13 +104,17 @@ Enables relative time formatting using the Intl.RelativeTimeFormat API:
104
104
 
105
105
  When `relative` is set to `true`, the component also accepts properties from [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat):
106
106
 
107
+ ::warning
108
+ Due to `style` being a reserved prop, `relativeStyle` prop is used instead.
109
+ ::
110
+
107
111
  ```vue
108
112
  <template>
109
113
  <NuxtTime
110
114
  :datetime="Date.now() - 3 * 24 * 60 * 60 * 1000"
111
115
  relative
112
116
  numeric="auto"
113
- style="long"
117
+ relative-style="long"
114
118
  />
115
119
  </template>
116
120
  ```
@@ -102,6 +102,7 @@ The `handler` function should be **side-effect free** to ensure predictable beha
102
102
  - `dedupe`: avoid fetching same key more than once at a time (defaults to `cancel`). Possible options:
103
103
  - `cancel` - cancels existing requests when a new one is made
104
104
  - `defer` - does not make new requests at all if there is a pending request
105
+ - `timeout` - a number in milliseconds to wait before timing out the request (defaults to `undefined`, which means no timeout)
105
106
 
106
107
  ::note
107
108
  Under the hood, `lazy: false` uses `<Suspense>` to block the loading of the route before the data has been fetched. Consider using `lazy: true` and implementing a loading state instead for a snappier user experience.
@@ -170,12 +171,12 @@ If you have not fetched data on the server (for example, with `server: false`),
170
171
 
171
172
  ```ts [Signature]
172
173
  export function useAsyncData<DataT, DataE> (
173
- handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
174
+ handler: (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<DataT>,
174
175
  options?: AsyncDataOptions<DataT>
175
176
  ): AsyncData<DataT, DataE>
176
177
  export function useAsyncData<DataT, DataE> (
177
178
  key: MaybeRefOrGetter<string>,
178
- handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
179
+ handler: (nuxtApp: NuxtApp, options: { signal: AbortSignal }) => Promise<DataT>,
179
180
  options?: AsyncDataOptions<DataT>
180
181
  ): Promise<AsyncData<DataT, DataE>>
181
182
 
@@ -190,6 +191,7 @@ type AsyncDataOptions<DataT> = {
190
191
  pick?: string[]
191
192
  watch?: MultiWatchSources | false
192
193
  getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
194
+ timeout?: number
193
195
  }
194
196
 
195
197
  type AsyncDataRequestContext = {
@@ -208,6 +210,8 @@ type AsyncData<DataT, ErrorT> = {
208
210
 
209
211
  interface AsyncDataExecuteOptions {
210
212
  dedupe?: 'cancel' | 'defer'
213
+ timeout?: number
214
+ signal?: AbortSignal
211
215
  }
212
216
 
213
217
  type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
@@ -145,6 +145,7 @@ type UseFetchOptions<DataT> = {
145
145
  getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
146
146
  deep?: boolean
147
147
  dedupe?: 'cancel' | 'defer'
148
+ timeout?: number
148
149
  default?: () => DataT
149
150
  transform?: (input: DataT) => DataT | Promise<DataT>
150
151
  pick?: string[]
@@ -169,6 +170,8 @@ type AsyncData<DataT, ErrorT> = {
169
170
 
170
171
  interface AsyncDataExecuteOptions {
171
172
  dedupe?: 'cancel' | 'defer'
173
+ timeout?: number
174
+ signal?: AbortSignal
172
175
  }
173
176
 
174
177
  type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
@@ -195,6 +198,7 @@ type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
195
198
  | `lazy` | `boolean` | `false` | If true, resolves after route loads (does not block navigation). |
196
199
  | `immediate` | `boolean` | `true` | If false, prevents request from firing immediately. |
197
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) |
198
202
  | `transform` | `(input: DataT) => DataT \| Promise<DataT>` | - | Function to transform the result after resolving. |
199
203
  | `getCachedData`| `(key, nuxtApp, ctx) => DataT \| undefined` | - | Function to return cached data. See below for default. |
200
204
  | `pick` | `string[]` | - | Only pick specified keys from the result. |
@@ -8,7 +8,7 @@ links:
8
8
  size: xs
9
9
  ---
10
10
 
11
- Modules are the building blocks of Nuxt. Kit provides a set of utilities to help you create and use modules. You can use these utilities to create your own modules or to reuse existing modules. For example, you can use the `defineNuxtModule` function to define a module and the `installModule` function to install a module programmatically.
11
+ Modules are the building blocks of Nuxt. Kit provides a set of utilities to help you create and use modules. You can use these utilities to create your own modules or to reuse existing modules. For example, you can use the `defineNuxtModule` function to define a module and specify dependencies using the `moduleDependencies` option.
12
12
 
13
13
  ## `defineNuxtModule`
14
14
 
@@ -62,6 +62,7 @@ export function defineNuxtModule<TOptions extends ModuleOptions> (): {
62
62
  | `defaults` | `T \| ((nuxt: Nuxt) => T)`{lang="ts"} | `false` | Default options for the module. If a function is provided, it will be called with the Nuxt instance as the first argument. |
63
63
  | `schema` | `T` | `false` | Schema for the module options. If provided, options will be applied to the schema. |
64
64
  | `hooks` | `Partial<NuxtHooks>`{lang="ts"} | `false` | Hooks to be installed for the module. If provided, the module will install the hooks. |
65
+ | `moduleDependencies` | `Record<string, ModuleDependency> \| ((nuxt: Nuxt) => Record<string, ModuleDependency>)`{lang="ts"} | `false` | Dependencies on other modules with version constraints and configuration. Can be an object or a function that receives the Nuxt instance. See [example](#specifying-module-dependencies). |
65
66
  | `onInstall` | `(nuxt: Nuxt) => Awaitable<void>`{lang="ts"} | `false` | Lifecycle hook called when the module is first installed. Requires `meta.name` and `meta.version` to be defined. |
66
67
  | `onUpgrade` | `(options: T, nuxt: Nuxt, previousVersion: string) => Awaitable<void>`{lang="ts"} | `false` | Lifecycle hook called when the module is upgraded to a newer version. Requires `meta.name` and `meta.version` to be defined. |
67
68
  | `setup` | `(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void \| false \| ModuleSetupInstallResult>`{lang="ts"} | `false` | Setup function for the module. If provided, the module will call the setup function. |
@@ -239,8 +240,93 @@ export default defineNuxtModule({
239
240
  })
240
241
  ```
241
242
 
243
+ #### Specifying Module Dependencies
244
+
245
+ You can use the `moduleDependencies` option to declare dependencies on other modules. This provides a robust way to ensure proper setup order, version compatibility, and configuration management.
246
+
247
+ The `moduleDependencies` option can be either an object or a function that receives the Nuxt instance:
248
+
249
+ ##### Example
250
+
251
+ ```ts
252
+ import { defineNuxtModule } from '@nuxt/kit'
253
+
254
+ export default defineNuxtModule({
255
+ meta: {
256
+ name: 'my-module',
257
+ },
258
+ moduleDependencies: {
259
+ '@nuxtjs/tailwindcss': {
260
+ // Specify a version constraint (semver format)
261
+ version: '>=6.0.0',
262
+ // Configuration that overrides user settings
263
+ overrides: {
264
+ exposeConfig: true,
265
+ },
266
+ // Configuration that sets defaults but respects user settings
267
+ defaults: {
268
+ config: {
269
+ darkMode: 'class',
270
+ },
271
+ },
272
+ },
273
+ '@nuxtjs/fontaine': {
274
+ // Optional dependencies won't be installed but ensure that options
275
+ // can be set if they _are_ installed
276
+ optional: true,
277
+ defaults: {
278
+ fonts: [
279
+ {
280
+ family: 'Roboto',
281
+ fallbacks: ['Impact'],
282
+ },
283
+ ],
284
+ },
285
+ },
286
+ },
287
+ setup (options, nuxt) {
288
+
289
+ },
290
+ })
291
+ ```
292
+
293
+ You can also use a function to dynamically determine dependencies based on the Nuxt configuration:
294
+
295
+ ```ts
296
+ import { defineNuxtModule } from '@nuxt/kit'
297
+
298
+ export default defineNuxtModule({
299
+ meta: {
300
+ name: 'my-module',
301
+ },
302
+ moduleDependencies (nuxt) {
303
+ const dependencies: Record<string, any> = {
304
+ '@nuxtjs/tailwindcss': {
305
+ version: '>=6.0.0',
306
+ },
307
+ }
308
+
309
+ // Conditionally add dependencies based on Nuxt config
310
+ if (nuxt.options.experimental?.someFeature) {
311
+ dependencies['@nuxtjs/fontaine'] = {
312
+ optional: true,
313
+ }
314
+ }
315
+
316
+ return dependencies
317
+ },
318
+ setup (options, nuxt) {
319
+ // Your setup logic runs after all dependencies are initialized
320
+ },
321
+ })
322
+ ```
323
+
242
324
  ## `installModule`
243
325
 
326
+ ::callout{type="warning"}
327
+ **Deprecated:** Use the [`moduleDependencies`](#specifying-module-dependencies) option in `defineNuxtModule` instead. The `installModule` function will be removed (or may become non-blocking) in a future version.
328
+ ::
329
+
244
330
  Install specified Nuxt module programmatically. This is helpful when your module depends on other modules. You can pass the module options as an object to `inlineOptions` and they will be passed to the module's `setup` function.
245
331
 
246
332
  ### Usage
@@ -197,6 +197,10 @@ Add plugin to extend Nitro's runtime behavior.
197
197
  You can read more about Nitro plugins in the [Nitro documentation](https://nitro.build/guide/plugins).
198
198
  ::
199
199
 
200
+ ::warning
201
+ It is necessary to explicitly import `defineNitroPlugin` from `nitropack/runtime` within your plugin file. The same requirement applies to utilities such as `useRuntimeConfig`.
202
+ ::
203
+
200
204
  ### Usage
201
205
 
202
206
  ```ts twoslash
@@ -14,6 +14,10 @@ Nuxt have builders based on [Vite](https://github.com/nuxt/nuxt/tree/main/packag
14
14
 
15
15
  Extends the Vite configuration. Callback function can be called multiple times, when applying to both client and server builds.
16
16
 
17
+ ::warning
18
+ This hook is now deprecated, and we recommend using a Vite plugin instead with a `config` hook, or &mdash; for environment-specific configuration &mdash; the `applyToEnvironment` hook.
19
+ ::
20
+
17
21
  ### Usage
18
22
 
19
23
  ```ts twoslash
@@ -30,6 +34,45 @@ export default defineNuxtModule({
30
34
  })
31
35
  ```
32
36
 
37
+ For environment-specific configuration in Nuxt 5+, use `addVitePlugin()` instead:
38
+
39
+ ```ts twoslash
40
+ import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
41
+
42
+ export default defineNuxtModule({
43
+ setup () {
44
+ // For global configuration (affects all environments)
45
+ addVitePlugin(() => ({
46
+ name: 'my-global-plugin',
47
+ config (config) {
48
+ // This runs before environment setup
49
+ config.optimizeDeps ||= {}
50
+ config.optimizeDeps.include ||= []
51
+ config.optimizeDeps.include.push('cross-fetch')
52
+ },
53
+ }))
54
+
55
+ // For environment-specific configuration
56
+ addVitePlugin(() => ({
57
+ name: 'my-client-plugin',
58
+ applyToEnvironment (environment) {
59
+ return environment.name === 'client'
60
+ },
61
+ configEnvironment (name, config) {
62
+ // This only affects the client environment
63
+ config.optimizeDeps ||= {}
64
+ config.optimizeDeps.include ||= []
65
+ config.optimizeDeps.include.push('client-only-package')
66
+ },
67
+ }))
68
+ },
69
+ })
70
+ ```
71
+
72
+ ::warning
73
+ **Important:** The `config` hook runs before `applyToEnvironment` and modifies the global configuration. Use `configEnvironment` for environment-specific configuration changes.
74
+ ::
75
+
33
76
  ### Type
34
77
 
35
78
  ```ts twoslash
@@ -54,8 +97,8 @@ Checkout Vite website for more information about its configuration.
54
97
  | --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ |
55
98
  | `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. |
56
99
  | `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. |
57
- | `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. |
58
- | `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. |
100
+ | `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. **Deprecated in Nuxt 5+.** Use `addVitePlugin()` with `applyToEnvironment()` instead. |
101
+ | `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. **Deprecated in Nuxt 5+.** Use `addVitePlugin()` with `applyToEnvironment()` instead. |
59
102
  | `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. |
60
103
 
61
104
  ## `extendWebpackConfig`
@@ -111,6 +154,10 @@ Checkout webpack website for more information about its configuration.
111
154
 
112
155
  Append Vite plugin to the config.
113
156
 
157
+ ::warning
158
+ In Nuxt 5+, plugins registered with `server: false` or `client: false` options will not have their `config` or `configResolved` hooks called. Instead, use the `applyToEnvironment()` method instead for environment-specific plugins.
159
+ ::
160
+
114
161
  ### Usage
115
162
 
116
163
  ```ts twoslash
@@ -131,6 +178,15 @@ export default defineNuxtModule({
131
178
  },
132
179
  setup (options) {
133
180
  addVitePlugin(svg4VuePlugin(options.svg4vue))
181
+
182
+ // or, to add a vite plugin to only one environment
183
+ addVitePlugin(() => ({
184
+ name: 'my-client-plugin',
185
+ applyToEnvironment (environment) {
186
+ return environment.name === 'client'
187
+ },
188
+ // ... rest of your client-only plugin
189
+ }))
134
190
  },
135
191
  })
136
192
  ```
@@ -159,8 +215,8 @@ See [Vite website](https://vite.dev/guide/api-plugin.html) for more information
159
215
  | --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ |
160
216
  | `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. |
161
217
  | `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. |
162
- | `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. |
163
- | `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. |
218
+ | `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. **Deprecated in Nuxt 5+.** Use `applyToEnvironment()` instead. |
219
+ | `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. **Deprecated in Nuxt 5+.** Use `applyToEnvironment()` instead. |
164
220
  | `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. |
165
221
 
166
222
  ## `addWebpackPlugin`
@@ -22,11 +22,9 @@ import { buildNuxt, loadNuxt } from '@nuxt/kit'
22
22
  async function getViteConfig () {
23
23
  const nuxt = await loadNuxt({ cwd: process.cwd(), dev: false, overrides: { ssr: false } })
24
24
  return new Promise((resolve, reject) => {
25
- nuxt.hook('vite:extendConfig', (config, { isClient }) => {
26
- if (isClient) {
27
- resolve(config)
28
- throw new Error('_stop_')
29
- }
25
+ nuxt.hook('vite:extend', (config) => {
26
+ resolve(config)
27
+ throw new Error('_stop_')
30
28
  })
31
29
  buildNuxt(nuxt).catch((err) => {
32
30
  if (!err.toString().includes('_stop_')) {
@@ -113,6 +113,7 @@ function addComponent (options: AddComponentOptions): void
113
113
  | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
114
114
  | `name` | `string` | `true` | Component name. |
115
115
  | `filePath` | `string` | `true` | Path to the component. |
116
+ | `declarationPath` | `string` | `false` | Path to component's declaration file. It is used to generate components' [type templates](/docs/4.x/api/kit/templates#addtypetemplate); if not provided, `filePath` is used instead. |
116
117
  | `pascalName` | `string` | `false` | Pascal case component name. If not provided, it will be generated from the component name. |
117
118
  | `kebabName` | `string` | `false` | Kebab case component name. If not provided, it will be generated from the component name. |
118
119
  | `export` | `string` | `false` | Specify named or default export. If not provided, it will be set to `'default'`. |
@@ -0,0 +1,132 @@
1
+ ---
2
+ title: Head
3
+ description: Nuxt Kit provides utilities to help you manage head configuration in modules.
4
+ links:
5
+ - label: Source
6
+ icon: i-simple-icons-github
7
+ to: https://github.com/nuxt/nuxt/blob/main/packages/kit/src/head.ts
8
+ size: xs
9
+ ---
10
+
11
+ ## `setGlobalHead`
12
+
13
+ Sets global head configuration for your Nuxt application. This utility allows modules to programmatically configure meta tags, links, scripts, and other head elements that will be applied across all pages.
14
+
15
+ The provided head configuration will be merged with any existing head configuration using deep merging, with your provided values taking precedence.
16
+
17
+ ::tip
18
+ This is particularly useful for modules that need to inject global meta tags, stylesheets, or scripts into the application head.
19
+ ::
20
+
21
+ ### Type
22
+
23
+ ```ts twoslash
24
+ // @errors: 2391
25
+ // ---cut---
26
+ import type { SerializableHead } from '@unhead/vue/types'
27
+
28
+ interface AppHeadMetaObject extends SerializableHead {
29
+ charset?: string
30
+ viewport?: string
31
+ }
32
+
33
+ function setGlobalHead (head: AppHeadMetaObject): void
34
+ ```
35
+
36
+ ### Parameters
37
+
38
+ #### `head`
39
+
40
+ **Type**: `AppHeadMetaObject`
41
+
42
+ An object containing head configuration. All properties are optional and will be merged with existing configuration:
43
+
44
+ - `charset`: Character encoding for the document
45
+ - `viewport`: Viewport meta tag configuration
46
+ - `meta`: Array of meta tag objects
47
+ - `link`: Array of link tag objects (stylesheets, icons, etc.)
48
+ - `style`: Array of inline style tag objects
49
+ - `script`: Array of script tag objects
50
+ - `noscript`: Array of noscript tag objects
51
+ - `title`: Default page title
52
+ - `titleTemplate`: Template for formatting page titles
53
+ - `bodyAttrs`: Attributes to add to the `<body>` tag
54
+ - `htmlAttrs`: Attributes to add to the `<html>` tag
55
+
56
+ ### Examples
57
+
58
+ #### Adding Global Meta Tags
59
+
60
+ ```ts
61
+ import { defineNuxtModule, setGlobalHead } from '@nuxt/kit'
62
+
63
+ export default defineNuxtModule({
64
+ setup () {
65
+ setGlobalHead({
66
+ meta: [
67
+ { name: 'theme-color', content: '#ffffff' },
68
+ { name: 'author', content: 'Your Name' },
69
+ ],
70
+ })
71
+ },
72
+ })
73
+ ```
74
+
75
+ #### Injecting Global Stylesheets
76
+
77
+ ```ts
78
+ import { defineNuxtModule, setGlobalHead } from '@nuxt/kit'
79
+
80
+ export default defineNuxtModule({
81
+ setup () {
82
+ setGlobalHead({
83
+ link: [
84
+ {
85
+ rel: 'stylesheet',
86
+ href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap',
87
+ },
88
+ ],
89
+ })
90
+ },
91
+ })
92
+ ```
93
+
94
+ #### Adding Global Scripts
95
+
96
+ ```ts
97
+ import { defineNuxtModule, setGlobalHead } from '@nuxt/kit'
98
+
99
+ export default defineNuxtModule({
100
+ setup () {
101
+ setGlobalHead({
102
+ script: [
103
+ {
104
+ src: 'https://cdn.example.com/analytics.js',
105
+ async: true,
106
+ defer: true,
107
+ },
108
+ ],
109
+ })
110
+ },
111
+ })
112
+ ```
113
+
114
+ #### Setting HTML Attributes
115
+
116
+ ```ts
117
+ import { defineNuxtModule, setGlobalHead } from '@nuxt/kit'
118
+
119
+ export default defineNuxtModule({
120
+ setup () {
121
+ setGlobalHead({
122
+ htmlAttrs: {
123
+ lang: 'en',
124
+ dir: 'ltr',
125
+ },
126
+ bodyAttrs: {
127
+ class: 'custom-body-class',
128
+ },
129
+ })
130
+ },
131
+ })
132
+ ```
@@ -75,8 +75,8 @@ Hook | Arguments | Description
75
75
  `schema:beforeWrite` | `schema` | Called before writing the given schema.
76
76
  `schema:written` | - | Called after the schema is written.
77
77
  `vite:extend` | `viteBuildContext` | Allows extending Vite default context.
78
- `vite:extendConfig` | `viteInlineConfig, env` | Allows extending Vite default config.
79
- `vite:configResolved` | `viteInlineConfig, env` | Allows reading the resolved Vite config.
78
+ `vite:extendConfig` | `viteInlineConfig, env` | Allows extending Vite default config. **Deprecated in Nuxt 5+.** In Nuxt 5, this operates on a shared configuration rather than separate client/server configs.
79
+ `vite:configResolved` | `viteInlineConfig, env` | Allows reading the resolved Vite config. **Deprecated in Nuxt 5+.** In Nuxt 5, this operates on a shared configuration rather than separate client/server configs.
80
80
  `vite:serverCreated` | `viteServer, env` | Called when the Vite server is created.
81
81
  `vite:compiled` | - | Called after Vite server is compiled.
82
82
  `webpack:config` | `webpackConfigs` | Called before configuring the webpack compiler.
@@ -424,9 +424,60 @@ A unique identifier matching the build. This may contain the hash of the current
424
424
 
425
425
  The builder to use for bundling the Vue part of your application.
426
426
 
427
- - **Type**: `string`
427
+ Nuxt supports multiple builders for the client-side application. By default, Vite is used, but you can switch to webpack, Rspack, or even provide a custom builder implementation.
428
+
429
+ - **Type**: `'vite' | 'webpack' | 'rspack' | string | { bundle: (nuxt: Nuxt) => Promise<void> }`
428
430
  - **Default:** `"@nuxt/vite-builder"`
429
431
 
432
+ **Using supported builders:**
433
+
434
+ ```ts
435
+ export default defineNuxtConfig({
436
+ // default - uses @nuxt/vite-builder
437
+ // builder: 'vite',
438
+
439
+ // uses @nuxt/webpack-builder
440
+ // builder: 'webpack',
441
+
442
+ // uses @nuxt/rspack-builder
443
+ builder: 'rspack',
444
+ })
445
+ ```
446
+
447
+ If you are using `webpack` or `rspack` you will need to make sure `@nuxt/webpack-builder` or `@nuxt/rspack-builder` is explicitly installed in your project.
448
+
449
+ **Using a custom builder object:**
450
+
451
+ You can provide a custom builder by passing an object with a `bundle` function:
452
+
453
+ ```ts
454
+ export default defineNuxtConfig({
455
+ builder: {
456
+ async bundle (nuxt) {
457
+ const entry = await resolvePath(resolve(nuxt.options.appDir, 'entry'))
458
+
459
+ // Build client and server bundles
460
+ await buildClient(nuxt, entry)
461
+ if (nuxt.options.ssr) {
462
+ await buildServer(nuxt, entry)
463
+ }
464
+
465
+ // ... it's a bit more complicated than that, of course!
466
+ },
467
+ },
468
+ })
469
+ ```
470
+
471
+ **Creating a custom builder package:**
472
+
473
+ To create a custom builder as a separate package, it should export a `bundle` function. You can then specify the package name in your `nuxt.config.ts`:
474
+
475
+ ```ts
476
+ export default defineNuxtConfig({
477
+ builder: 'my-custom-builder',
478
+ })
479
+ ```
480
+
430
481
  ## compatibilityDate
431
482
 
432
483
  Specify a compatibility date for your app.
@@ -668,7 +719,8 @@ Configure shared esbuild options used within Nuxt and passed to other builders,
668
719
 
669
720
  ## experimental
670
721
 
671
- ::read-more{to="/docs/4.x/guide/going-further/experimental-features"} Learn more about Nuxt's experimental features.
722
+ ::read-more{to="/docs/4.x/guide/going-further/experimental-features"}
723
+ Learn more about Nuxt's experimental features.
672
724
  ::
673
725
 
674
726
  ## extends
@@ -701,12 +753,14 @@ The extensions that should be resolved by the Nuxt resolver.
701
753
 
702
754
  ## features
703
755
 
704
- ::read-more{to="/docs/4.x/guide/going-further/features#features"} Learn more about Nuxt's opt-in features.
756
+ ::read-more{to="/docs/4.x/guide/going-further/features#features"}
757
+ Learn more about Nuxt's opt-in features.
705
758
  ::
706
759
 
707
760
  ## future
708
761
 
709
- ::read-more{to="/docs/4.x/guide/going-further/features#features"} Learn more about opting-in to new features that will become default in a future (possibly major) version of the framework,
762
+ ::read-more{to="/docs/4.x/guide/going-further/features#features"}
763
+ Learn more about opting-in to new features that will become default in a future (possibly major) version of the framework.
710
764
  ::
711
765
 
712
766
  ## hooks
@@ -1218,6 +1272,23 @@ export default defineNuxtConfig({
1218
1272
  })
1219
1273
  ```
1220
1274
 
1275
+ ## server
1276
+
1277
+ Configuration for Nuxt's server builder.
1278
+
1279
+ ### `builder`
1280
+
1281
+ Specify the server builder to use for bundling the server part of your application.
1282
+
1283
+ By default, Nuxt uses `@nuxt/nitro-server`, which provides standalone Nitro integration. This architecture allows for different Nitro integration patterns, such as using Nitro as a Vite plugin (with the Vite Environment API).
1284
+
1285
+ - **Type**: `string | { bundle: (nuxt: Nuxt) => Promise<void> }`
1286
+ - **Default:** `"@nuxt/nitro-server"`
1287
+
1288
+ ::callout{type="warning"}
1289
+ This option is intended for internal use and the API is not finalized. Please open an issue before relying on the current implementation.
1290
+ ::
1291
+
1221
1292
  ## serverDir
1222
1293
 
1223
1294
  Define the server directory of your Nuxt application, where Nitro routes, middleware and plugins are kept.
@@ -31,8 +31,8 @@ If your issue concerns Vue or Vite, please try to reproduce it first with the Vu
31
31
  **Nuxt**:
32
32
 
33
33
  ::card-group
34
- :card{title="Nuxt on StackBlitz" icon="i-simple-icons-stackblitz" to="https://nuxt.new/s/v3" target="_blank"}
35
- :card{title="Nuxt on CodeSandbox" icon="i-simple-icons-codesandbox" to="https://nuxt.new/c/v3" target="_blank"}
34
+ :card{title="Nuxt on StackBlitz" icon="i-simple-icons-stackblitz" to="https://nuxt.new/s/v4" target="_blank"}
35
+ :card{title="Nuxt on CodeSandbox" icon="i-simple-icons-codesandbox" to="https://nuxt.new/c/v4" target="_blank"}
36
36
  ::
37
37
 
38
38
  **Vue**:
@@ -32,7 +32,7 @@ Milestone | Expected date | Notes
32
32
  -------------|---------------|------------------------------------------------------------------------|-----------------------
33
33
  SEO & PWA | 2025 | [nuxt/nuxt#18395](https://github.com/nuxt/nuxt/discussions/18395) | Migrating from [nuxt-community/pwa-module](https://github.com/nuxt-community/pwa-module) for built-in SEO utils and service worker support
34
34
  Assets | 2025 | [nuxt/nuxt#22012](https://github.com/nuxt/nuxt/discussions/22012) | Allow developers and modules to handle loading third-party assets.
35
- Translations | - | [nuxt/translations#4](https://github.com/nuxt/translations/discussions/4) ([request access](https://github.com/nuxt/nuxt/discussions/16054)) | A collaborative project for a stable translation process for Nuxt docs. Currently pending for ideas and documentation tooling support (content v2 with remote sources).
35
+ Translations | - | [nuxt/nuxt.com#1711](https://github.com/nuxt/nuxt.com/issues/1711) | A collaborative project for a stable translation process for Nuxt docs. Currently pending for ideas and documentation tooling support.
36
36
 
37
37
  ## Core Modules Roadmap
38
38
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/docs",
3
- "version": "4.1.3",
3
+ "version": "4.2.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",