@nuxt/docs 3.18.1 → 3.19.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.
- package/1.getting-started/07.routing.md +1 -1
- package/1.getting-started/11.state-management.md +2 -2
- package/1.getting-started/14.layers.md +21 -0
- package/1.getting-started/17.testing.md +71 -18
- package/1.getting-started/18.upgrade.md +11 -2
- package/2.guide/1.concepts/8.typescript.md +14 -0
- package/2.guide/2.directory-structure/1.middleware.md +38 -0
- package/2.guide/2.directory-structure/1.pages.md +1 -1
- package/2.guide/3.going-further/1.experimental-features.md +33 -0
- package/2.guide/3.going-further/3.modules.md +17 -0
- package/2.guide/3.going-further/7.layers.md +24 -0
- package/3.api/2.composables/use-route.md +37 -2
- package/3.api/4.commands/init.md +2 -1
- package/3.api/5.kit/16.layers.md +220 -0
- package/5.community/6.roadmap.md +6 -6
- package/package.json +1 -1
|
@@ -51,7 +51,7 @@ The [`<NuxtLink>`](/docs/api/components/nuxt-link) component links pages between
|
|
|
51
51
|
|
|
52
52
|
When a [`<NuxtLink>`](/docs/api/components/nuxt-link) enters the viewport on the client side, Nuxt will automatically prefetch components and payload (generated pages) of the linked pages ahead of time, resulting in faster navigation.
|
|
53
53
|
|
|
54
|
-
```vue [pages/
|
|
54
|
+
```vue [pages/index.vue]
|
|
55
55
|
<template>
|
|
56
56
|
<header>
|
|
57
57
|
<nav>
|
|
@@ -178,8 +178,8 @@ const date = useLocaleDate(new Date('2016-10-26'))
|
|
|
178
178
|
<p>{{ date }}</p>
|
|
179
179
|
<label for="locale-chooser">Preview a different locale</label>
|
|
180
180
|
<select id="locale-chooser" v-model="locale">
|
|
181
|
-
<option v-for="
|
|
182
|
-
{{
|
|
181
|
+
<option v-for="loc of locales" :key="loc" :value="loc">
|
|
182
|
+
{{ loc }}
|
|
183
183
|
</option>
|
|
184
184
|
</select>
|
|
185
185
|
</div>
|
|
@@ -75,6 +75,27 @@ export default defineNuxtConfig({
|
|
|
75
75
|
|
|
76
76
|
Nuxt uses [unjs/c12](https://c12.unjs.io) and [unjs/giget](https://giget.unjs.io) for extending remote layers. Check the documentation for more information and all available options.
|
|
77
77
|
|
|
78
|
+
## Layer Priority
|
|
79
|
+
|
|
80
|
+
When using multiple layers, it's important to understand how they override each other:
|
|
81
|
+
|
|
82
|
+
1. **Layers in `extends`** - earlier entries have higher priority (first overrides second)
|
|
83
|
+
2. **Auto-scanned local layers** from `~~/layers` directory in alphabetical order (Z overrides A)
|
|
84
|
+
3. **Your project** has the highest priority in the stack - it will always override other layers
|
|
85
|
+
|
|
86
|
+
```ts [nuxt.config.ts]
|
|
87
|
+
export default defineNuxtConfig({
|
|
88
|
+
extends: [
|
|
89
|
+
'../base', // Highest priority (among extends)
|
|
90
|
+
'@my-themes/awesome', // Medium priority
|
|
91
|
+
'github:my-themes/awesome#v1', // Lower priority
|
|
92
|
+
]
|
|
93
|
+
// Your project has the highest priority
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This means if multiple layers define the same component, configuration, or file, the one with higher priority will be used.
|
|
98
|
+
|
|
78
99
|
::read-more{to="/docs/guide/going-further/layers"}
|
|
79
100
|
Read more about layers in the **Layer Author Guide**.
|
|
80
101
|
::
|
|
@@ -54,10 +54,28 @@ We currently ship an environment for unit testing code that needs a [Nuxt](https
|
|
|
54
54
|
2. Create a `vitest.config.ts` with the following content:
|
|
55
55
|
|
|
56
56
|
```ts twoslash
|
|
57
|
-
import {
|
|
57
|
+
import { defineConfig } from 'vitest/config'
|
|
58
|
+
import { defineVitestProject } from '@nuxt/test-utils/config'
|
|
58
59
|
|
|
59
|
-
export default
|
|
60
|
-
|
|
60
|
+
export default defineConfig({
|
|
61
|
+
test: {
|
|
62
|
+
projects: [
|
|
63
|
+
{
|
|
64
|
+
test: {
|
|
65
|
+
name: 'unit',
|
|
66
|
+
include: ['test/{e2e,unit}/*.{test,spec}.ts'],
|
|
67
|
+
environment: 'node',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
await defineVitestProject({
|
|
71
|
+
test: {
|
|
72
|
+
name: 'nuxt',
|
|
73
|
+
include: ['test/nuxt/*.{test,spec}.ts'],
|
|
74
|
+
environment: 'nuxt',
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
],
|
|
78
|
+
},
|
|
61
79
|
})
|
|
62
80
|
```
|
|
63
81
|
|
|
@@ -72,24 +90,16 @@ It is possible to set environment variables for testing by using the `.env.test`
|
|
|
72
90
|
|
|
73
91
|
### Using a Nuxt Runtime Environment
|
|
74
92
|
|
|
75
|
-
|
|
93
|
+
Using [Vitest projects](https://vitest.dev/guide/projects.html#test-projects), you have fine-grained control over which tests run in which environment:
|
|
76
94
|
|
|
77
|
-
|
|
95
|
+
- **Unit tests**: Place regular unit tests in `test/unit/` - these run in a Node environment for speed
|
|
96
|
+
- **Nuxt tests**: Place tests that rely on the Nuxt runtime environment in `test/nuxt/` - these will run within a Nuxt runtime environment
|
|
78
97
|
|
|
79
|
-
|
|
80
|
-
// @vitest-environment nuxt
|
|
81
|
-
import { test } from 'vitest'
|
|
98
|
+
#### Alternative: Simple Setup
|
|
82
99
|
|
|
83
|
-
|
|
84
|
-
// ... test with Nuxt environment!
|
|
85
|
-
})
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
You can alternatively set `environment: 'nuxt'` in your Vitest configuration to enable the Nuxt environment for **all tests**.
|
|
100
|
+
If you prefer a simpler setup and want all tests to run in the Nuxt environment, you can use the basic configuration:
|
|
89
101
|
|
|
90
102
|
```ts twoslash
|
|
91
|
-
// vitest.config.ts
|
|
92
|
-
import { fileURLToPath } from 'node:url'
|
|
93
103
|
import { defineVitestConfig } from '@nuxt/test-utils/config'
|
|
94
104
|
|
|
95
105
|
export default defineVitestConfig({
|
|
@@ -109,7 +119,7 @@ export default defineVitestConfig({
|
|
|
109
119
|
})
|
|
110
120
|
```
|
|
111
121
|
|
|
112
|
-
If you
|
|
122
|
+
If you're using the simple setup with `environment: 'nuxt'` by default, you can opt _out_ of the [Nuxt environment](https://vitest.dev/guide/environment.html#test-environment) per test file as needed.
|
|
113
123
|
|
|
114
124
|
```ts twoslash
|
|
115
125
|
// @vitest-environment node
|
|
@@ -120,6 +130,45 @@ test('my test', () => {
|
|
|
120
130
|
})
|
|
121
131
|
```
|
|
122
132
|
|
|
133
|
+
::warning
|
|
134
|
+
This approach is not recommended as it creates a hybrid environment where Nuxt Vite plugins run but the Nuxt entry and `nuxtApp` are not initialized. This can lead to hard-to-debug errors.
|
|
135
|
+
::
|
|
136
|
+
|
|
137
|
+
### Organizing Your Tests
|
|
138
|
+
|
|
139
|
+
With the project-based setup, you might organize your tests as follows:
|
|
140
|
+
|
|
141
|
+
```bash [Directory structure]
|
|
142
|
+
test/
|
|
143
|
+
├── e2e/
|
|
144
|
+
│ └── ssr.test.ts
|
|
145
|
+
├── nuxt/
|
|
146
|
+
│ ├── components.test.ts
|
|
147
|
+
│ └── composables.test.ts
|
|
148
|
+
├── unit/
|
|
149
|
+
│ └── utils.test.ts
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
You can of course opt for any test structure, but keeping the Nuxt runtime environment separated from Nuxt end-to-end tests is important for test stability.
|
|
153
|
+
|
|
154
|
+
#### Running Tests
|
|
155
|
+
|
|
156
|
+
With the project setup, you can run different test suites:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Run all tests
|
|
160
|
+
npx vitest
|
|
161
|
+
|
|
162
|
+
# Run only unit tests
|
|
163
|
+
npx vitest --project unit
|
|
164
|
+
|
|
165
|
+
# Run only Nuxt tests
|
|
166
|
+
npx vitest --project nuxt
|
|
167
|
+
|
|
168
|
+
# Run tests in watch mode
|
|
169
|
+
npx vitest --watch
|
|
170
|
+
```
|
|
171
|
+
|
|
123
172
|
::warning
|
|
124
173
|
When you run your tests within the Nuxt environment, they will be running in a [`happy-dom`](https://github.com/capricorn86/happy-dom) or [`jsdom`](https://github.com/jsdom/jsdom) environment. Before your tests run, a global Nuxt app will be initialized (including, for example, running any plugins or code you've defined in your `app.vue`).
|
|
125
174
|
|
|
@@ -555,7 +604,11 @@ Please use the options below for the `setup` method.
|
|
|
555
604
|
|
|
556
605
|
- `setupTimeout`: The amount of time (in milliseconds) to allow for `setupTest` to complete its work (which could include building or generating files for a Nuxt application, depending on the options that are passed).
|
|
557
606
|
- Type: `number`
|
|
558
|
-
- Default: `
|
|
607
|
+
- Default: `120000` or `240000` on windows
|
|
608
|
+
|
|
609
|
+
- `teardownTimeout`: The amount of time (in milliseconds) to allow tearing down the test environment, such as closing the browser.
|
|
610
|
+
- Type: `number`
|
|
611
|
+
- Default: `30000`
|
|
559
612
|
|
|
560
613
|
#### Features
|
|
561
614
|
|
|
@@ -1129,7 +1129,16 @@ However, to take advantage of improved type checking, you can opt in to the new
|
|
|
1129
1129
|
+ "typecheck": "nuxt prepare && vue-tsc -b --noEmit"
|
|
1130
1130
|
```
|
|
1131
1131
|
|
|
1132
|
-
4. **
|
|
1132
|
+
4. **Move all type augmentations into their appropriate context**:
|
|
1133
|
+
* If you are augmenting types for the app context, move the files to the `app/` directory.
|
|
1134
|
+
* If you are augmenting types for the server context, move the files to the `server/` directory.
|
|
1135
|
+
* If you are augmenting types that are **shared between the app and server**, move the files to the `shared/` directory.
|
|
1136
|
+
|
|
1137
|
+
::warning
|
|
1138
|
+
Augmenting types from outside the `app/`, `server/`, or `shared/` directories will not work with the new project references setup.
|
|
1139
|
+
::
|
|
1140
|
+
|
|
1141
|
+
5. **Configure Node.js TypeScript options** if needed:
|
|
1133
1142
|
<!-- @case-police-ignore tsConfig -->
|
|
1134
1143
|
|
|
1135
1144
|
```ts
|
|
@@ -1151,7 +1160,7 @@ However, to take advantage of improved type checking, you can opt in to the new
|
|
|
1151
1160
|
})
|
|
1152
1161
|
```
|
|
1153
1162
|
|
|
1154
|
-
|
|
1163
|
+
6. **Update any CI/build scripts** that run TypeScript checking to ensure they use the new project references approach.
|
|
1155
1164
|
|
|
1156
1165
|
The new configuration provides better type safety and IntelliSense for projects that opt in, while maintaining full backward compatibility for existing setups.
|
|
1157
1166
|
|
|
@@ -80,6 +80,20 @@ Overwriting options such as `"compilerOptions.paths"` with your own configuratio
|
|
|
80
80
|
In case you need to extend options provided by `./.nuxt/tsconfig.json` further, you can use the [`alias` property](/docs/api/nuxt-config#alias) within your `nuxt.config`. Nuxt will pick them up and extend `./.nuxt/tsconfig.json` accordingly.
|
|
81
81
|
::
|
|
82
82
|
|
|
83
|
+
### Augmenting Types with Project References
|
|
84
|
+
|
|
85
|
+
Since the project is divided into **multiple type contexts**, it's important to **augment types within the correct context** to ensure they are properly recognized.
|
|
86
|
+
|
|
87
|
+
For example, if you want to augment types for the `app` context, the augmentation file should be placed in the `app/` directory.
|
|
88
|
+
|
|
89
|
+
Similarly:
|
|
90
|
+
- For the `server` context, place the augmentation file in the `server/` directory.
|
|
91
|
+
- For types that are **shared between the app and server**, place the file in the `shared/` directory.
|
|
92
|
+
|
|
93
|
+
::warning
|
|
94
|
+
Augmenting types outside of these directories will not be recognized by TypeScript.
|
|
95
|
+
::
|
|
96
|
+
|
|
83
97
|
## Strict Checks
|
|
84
98
|
|
|
85
99
|
TypeScript comes with certain checks to give you more safety and analysis of your program.
|
|
@@ -142,6 +142,44 @@ This is true even if you throw an error in your middleware on the server, and an
|
|
|
142
142
|
Rendering an error page is an entirely separate page load, meaning any registered middleware will run again. You can use [`useError`](/docs/getting-started/error-handling#useerror) in middleware to check if an error is being handled.
|
|
143
143
|
::
|
|
144
144
|
|
|
145
|
+
## Accessing Route in Middleware
|
|
146
|
+
|
|
147
|
+
Always use the `to` and `from` parameters in your middleware to access the next and previous routes. Avoid using the [`useRoute()`](/docs/api/composables/use-route) composable in this context altogether.
|
|
148
|
+
There is **no concept of a "current route" in middleware**, as middleware can abort a navigation or redirect to a different route. The `useRoute()` composable will always be inaccurate in this context.
|
|
149
|
+
|
|
150
|
+
::warning
|
|
151
|
+
Sometimes, you might call a composable that uses `useRoute()` internally, which can trigger this warning even if there is no direct call in your middleware.
|
|
152
|
+
This leads to the **same issue as above**, so you should structure your functions to accept the route as an argument instead when they are used in middleware.
|
|
153
|
+
::
|
|
154
|
+
|
|
155
|
+
::code-group
|
|
156
|
+
```ts twoslash [middleware/access-route.ts]
|
|
157
|
+
// @errors: 2304
|
|
158
|
+
export default defineNuxtRouteMiddleware(to => {
|
|
159
|
+
// passing the route to the function to avoid calling `useRoute()` in middleware
|
|
160
|
+
doSomethingWithRoute(to)
|
|
161
|
+
|
|
162
|
+
// ❌ this will output a warning and is NOT recommended
|
|
163
|
+
callsRouteInternally()
|
|
164
|
+
})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```ts twoslash [utils/handle-route.ts]
|
|
168
|
+
// providing the route as an argument so that it can be used in middleware correctly
|
|
169
|
+
export function doSomethingWithRoute(route = useRoute()) {
|
|
170
|
+
// ...
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
```ts twoslash [utils/dont-do-this.ts]
|
|
174
|
+
// ❌ this function is not suitable for use in middleware
|
|
175
|
+
export function callsRouteInternally() {
|
|
176
|
+
const route = useRoute()
|
|
177
|
+
// ...
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
::
|
|
182
|
+
|
|
145
183
|
## Adding Middleware Dynamically
|
|
146
184
|
|
|
147
185
|
It is possible to add global or named route middleware manually using the [`addRouteMiddleware()`](/docs/api/utils/add-route-middleware) helper function, such as from within a plugin.
|
|
@@ -337,7 +337,7 @@ You may define a path matcher, if you have a more complex pattern than can be ex
|
|
|
337
337
|
|
|
338
338
|
#### `props`
|
|
339
339
|
|
|
340
|
-
Allows accessing the route `params` as props passed to the page component. See[the `vue-router` docs](https://router.vuejs.org/guide/essentials/passing-props) for more information.
|
|
340
|
+
Allows accessing the route `params` as props passed to the page component. See [the `vue-router` docs](https://router.vuejs.org/guide/essentials/passing-props) for more information.
|
|
341
341
|
|
|
342
342
|
### Typing Custom Metadata
|
|
343
343
|
|
|
@@ -688,3 +688,36 @@ export default defineNuxtConfig({
|
|
|
688
688
|
}
|
|
689
689
|
})
|
|
690
690
|
```
|
|
691
|
+
|
|
692
|
+
## entryImportMap
|
|
693
|
+
|
|
694
|
+
By default, Nuxt improves chunk stability by using an import map to resolve the entry chunk of the bundle.
|
|
695
|
+
|
|
696
|
+
This injects an import map at the top of your `<head>` tag:
|
|
697
|
+
|
|
698
|
+
```html
|
|
699
|
+
<script type="importmap">{"imports":{"#entry":"/_nuxt/DC5HVSK5.js"}}</script>
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
Within the script chunks emitted by Vite, imports will be from `#entry`. This means that changes to the entry will not invalidate chunks which are otherwise unchanged.
|
|
703
|
+
|
|
704
|
+
::note
|
|
705
|
+
Nuxt smartly disables this feature if you have configured `vite.build.target` to include a browser that doesn't support import maps, or if you have configured `vite.build.rollupOptions.output.entryFileNames` to a value that does not include `[hash]`.
|
|
706
|
+
::
|
|
707
|
+
|
|
708
|
+
If you need to disable this feature you can do so:
|
|
709
|
+
|
|
710
|
+
```ts twoslash [nuxt.config.ts]
|
|
711
|
+
export default defineNuxtConfig({
|
|
712
|
+
experimental: {
|
|
713
|
+
entryImportMap: false
|
|
714
|
+
},
|
|
715
|
+
// or, better, simply tell vite your desired target
|
|
716
|
+
// which nuxt will respect
|
|
717
|
+
vite: {
|
|
718
|
+
build: {
|
|
719
|
+
target: 'safari13'
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
})
|
|
723
|
+
```
|
|
@@ -177,6 +177,23 @@ export default defineNuxtModule({
|
|
|
177
177
|
defaults: {},
|
|
178
178
|
// Shorthand sugar to register Nuxt hooks
|
|
179
179
|
hooks: {},
|
|
180
|
+
// Configuration for other modules - this does not ensure the module runs before
|
|
181
|
+
// your module, but it allows you to change the other module's configuration before it runs
|
|
182
|
+
moduleDependencies: {
|
|
183
|
+
'some-module': {
|
|
184
|
+
// You can specify a version constraint for the module. If the user has a different
|
|
185
|
+
// version installed, Nuxt will throw an error on startup.
|
|
186
|
+
version: '>=2',
|
|
187
|
+
// By default moduleDependencies will be added to the list of modules to be installed
|
|
188
|
+
// by Nuxt unless `optional` is set.
|
|
189
|
+
optional: true,
|
|
190
|
+
// Any configuration that should override `nuxt.options`.
|
|
191
|
+
overrides: {},
|
|
192
|
+
// Any configuration that should be set. It will override module defaults but
|
|
193
|
+
// will not override any configuration set in `nuxt.options`.
|
|
194
|
+
defaults: {}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
180
197
|
// The function holding your module logic, it can be asynchronous
|
|
181
198
|
setup(moduleOptions, nuxt) {
|
|
182
199
|
// ...
|
|
@@ -18,6 +18,7 @@ Additionally, certain other files in the layer directory will be auto-scanned an
|
|
|
18
18
|
- [`components/*`](/docs/guide/directory-structure/components) - Extend the default components
|
|
19
19
|
- [`composables/*`](/docs/guide/directory-structure/composables) - Extend the default composables
|
|
20
20
|
- [`layouts/*`](/docs/guide/directory-structure/layouts) - Extend the default layouts
|
|
21
|
+
- [`middleware/*`](/docs/guide/directory-structure/middleware) - Extend the default middleware
|
|
21
22
|
- [`pages/*`](/docs/guide/directory-structure/pages) - Extend the default pages
|
|
22
23
|
- [`plugins/*`](/docs/guide/directory-structure/plugins) - Extend the default plugins
|
|
23
24
|
- [`server/*`](/docs/guide/directory-structure/server) - Extend the default server endpoints & middleware
|
|
@@ -65,6 +66,29 @@ Additionally, certain other files in the layer directory will be auto-scanned an
|
|
|
65
66
|
|
|
66
67
|
::
|
|
67
68
|
|
|
69
|
+
## Layer Priority
|
|
70
|
+
|
|
71
|
+
When extending from multiple layers, it's important to understand the priority order:
|
|
72
|
+
|
|
73
|
+
1. **Layers in `extends`** - earlier entries have higher priority (first overrides second)
|
|
74
|
+
2. **Auto-scanned local layers** from `~~/layers` directory in alphabetical order (Z overrides A)
|
|
75
|
+
3. **Your project** has the highest priority in the stack - it will always override other layers
|
|
76
|
+
|
|
77
|
+
For example:
|
|
78
|
+
|
|
79
|
+
```ts [nuxt.config.ts]
|
|
80
|
+
export default defineNuxtConfig({
|
|
81
|
+
extends: [
|
|
82
|
+
'./layers/base', // Highest priority (among extends)
|
|
83
|
+
'./layers/theme', // Medium priority
|
|
84
|
+
'./layers/custom' // Lower priority
|
|
85
|
+
]
|
|
86
|
+
// Your project has the highest priority
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If you also have auto-scanned layers like `~~/layers/a` and `~~/layers/z`, the complete override order would be: `base` > `theme` > `custom` > `z` > `a` > your project.
|
|
91
|
+
|
|
68
92
|
## Starter Template
|
|
69
93
|
|
|
70
94
|
To get started you can initialize a layer with the [nuxt/starter/layer template](https://github.com/nuxt/starter/tree/layer). This will create a basic structure you can build upon. Execute this command within the terminal to get started:
|
|
@@ -12,6 +12,12 @@ links:
|
|
|
12
12
|
Within the template of a Vue component, you can access the route using `$route`.
|
|
13
13
|
::
|
|
14
14
|
|
|
15
|
+
The `useRoute` composable is a wrapper around the identically named composable from `vue-router`, providing access to the current route in a Nuxt application.
|
|
16
|
+
|
|
17
|
+
The key difference is that in Nuxt, the composable ensures that the route is updated **only after** the page content has changed after navigation.
|
|
18
|
+
In contrast, the `vue-router` version updates the route **immediately**, which can lead to synchronization issues between different parts of the template
|
|
19
|
+
that rely on the route metadata, for example.
|
|
20
|
+
|
|
15
21
|
## Example
|
|
16
22
|
|
|
17
23
|
In the following example, we call an API via [`useFetch`](/docs/api/composables/use-fetch) using a dynamic page parameter - `slug` - as part of the URL.
|
|
@@ -45,8 +51,37 @@ Apart from dynamic parameters and query parameters, `useRoute()` also provides t
|
|
|
45
51
|
- `path`: encoded pathname section of the URL
|
|
46
52
|
- `redirectedFrom`: route location that was attempted to access before ending up on the current route location
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
## Common Pitfalls
|
|
55
|
+
|
|
56
|
+
### Route Synchronization Issues
|
|
57
|
+
|
|
58
|
+
It’s important to use the `useRoute()` composable from Nuxt rather than the one from `vue-router` to avoid synchronization issues during page navigation.
|
|
59
|
+
Importing `useRoute` directly from `vue-router` bypasses Nuxt's implementation.
|
|
60
|
+
|
|
61
|
+
```ts twoslash
|
|
62
|
+
// ❌ do not use `useRoute` from `vue-router`
|
|
63
|
+
// @errors: 2300
|
|
64
|
+
import { useRoute } from 'vue-router'
|
|
65
|
+
// ✅ use Nuxt's `useRoute` composable
|
|
66
|
+
import { useRoute } from '#app'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Calling `useRoute` in Middleware
|
|
70
|
+
|
|
71
|
+
Using `useRoute` in middleware is not recommended because it can lead to unexpected behavior.
|
|
72
|
+
There is no concept of a "current route" in middleware.
|
|
73
|
+
The `useRoute()` composable should only be used in the setup function of a Vue component or in a Nuxt plugin.
|
|
74
|
+
|
|
75
|
+
::warning
|
|
76
|
+
This applies to any composable that uses `useRoute()` internally too.
|
|
50
77
|
::
|
|
51
78
|
|
|
79
|
+
::read-more{to="/docs/4.x/guide/directory-structure/app/middleware"}
|
|
80
|
+
Read more about accessing the route in the middleware section.
|
|
81
|
+
::
|
|
82
|
+
|
|
83
|
+
### Hydration Issues with `route.fullPath`
|
|
84
|
+
|
|
85
|
+
Browsers don't send [URL fragments](https://url.spec.whatwg.org/#concept-url-fragment) (for example `#foo`) when making requests. So using `route.fullPath` to affect the template can trigger hydration issues because this will include the fragment on client but not the server.
|
|
86
|
+
|
|
52
87
|
:read-more{icon="i-simple-icons-vuedotjs" to="https://router.vuejs.org/api/type-aliases/RouteLocationNormalizedLoaded.html"}
|
package/3.api/4.commands/init.md
CHANGED
|
@@ -10,7 +10,7 @@ links:
|
|
|
10
10
|
|
|
11
11
|
<!--init-cmd-->
|
|
12
12
|
```bash [Terminal]
|
|
13
|
-
npm create nuxt@latest [DIR] [--cwd=<directory>] [-t, --template] [-f, --force] [--offline] [--preferOffline] [--no-install] [--gitInit] [--shell] [--packageManager]
|
|
13
|
+
npm create nuxt@latest [DIR] [--cwd=<directory>] [-t, --template] [-f, --force] [--offline] [--preferOffline] [--no-install] [--gitInit] [--shell] [--packageManager] [--nightly]
|
|
14
14
|
```
|
|
15
15
|
<!--/init-cmd-->
|
|
16
16
|
|
|
@@ -40,6 +40,7 @@ Option | Default | Description
|
|
|
40
40
|
`--packageManager` | | Package manager choice (npm, pnpm, yarn, bun)
|
|
41
41
|
`--modules` | | Nuxt modules to install (comma separated without spaces)
|
|
42
42
|
`--no-modules` | | Skip module installation prompt
|
|
43
|
+
`--nightly` | | Use Nuxt nightly release channel (3x or latest)
|
|
43
44
|
<!--/init-opts-->
|
|
44
45
|
|
|
45
46
|
## Environment variables
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Layers"
|
|
3
|
+
description: Nuxt Kit provides utilities to help you work with layers and their directory structures.
|
|
4
|
+
links:
|
|
5
|
+
- label: Source
|
|
6
|
+
icon: i-simple-icons-github
|
|
7
|
+
to: https://github.com/nuxt/nuxt/blob/main/packages/kit/src/layers.ts
|
|
8
|
+
size: xs
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Nuxt layers provide a powerful way to share and extend functionality across projects. When working with layers in modules, you often need to access directory paths from each layer. Nuxt Kit provides the `getLayerDirectories` utility to access resolved directory paths for all layers in your Nuxt application.
|
|
12
|
+
|
|
13
|
+
## `getLayerDirectories`
|
|
14
|
+
|
|
15
|
+
Get the resolved directory paths for all layers in a Nuxt application. This function provides a structured way to access layer directories without directly accessing the private `nuxt.options._layers` property.
|
|
16
|
+
|
|
17
|
+
### Usage
|
|
18
|
+
|
|
19
|
+
```ts twoslash
|
|
20
|
+
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
|
|
21
|
+
|
|
22
|
+
export default defineNuxtModule({
|
|
23
|
+
setup() {
|
|
24
|
+
const layerDirs = getLayerDirectories()
|
|
25
|
+
|
|
26
|
+
// Access directories from all layers
|
|
27
|
+
for (const [index, layer] of layerDirs.entries()) {
|
|
28
|
+
console.log(`Layer ${index}:`)
|
|
29
|
+
console.log(` Root: ${layer.root}`)
|
|
30
|
+
console.log(` App: ${layer.app}`)
|
|
31
|
+
console.log(` Server: ${layer.server}`)
|
|
32
|
+
console.log(` Pages: ${layer.appPages}`)
|
|
33
|
+
// ... other directories
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Type
|
|
40
|
+
|
|
41
|
+
```ts twoslash
|
|
42
|
+
// @errors: 2391
|
|
43
|
+
import type { Nuxt } from '@nuxt/schema'
|
|
44
|
+
// ---cut---
|
|
45
|
+
function getLayerDirectories(nuxt?: Nuxt): LayerDirectories[]
|
|
46
|
+
|
|
47
|
+
interface LayerDirectories {
|
|
48
|
+
/** Nuxt rootDir (`/` by default) */
|
|
49
|
+
readonly root: string
|
|
50
|
+
/** Nitro source directory (`/server` by default) */
|
|
51
|
+
readonly server: string
|
|
52
|
+
/** Local modules directory (`/modules` by default) */
|
|
53
|
+
readonly modules: string
|
|
54
|
+
/** Shared directory (`/shared` by default) */
|
|
55
|
+
readonly shared: string
|
|
56
|
+
/** Public directory (`/public` by default) */
|
|
57
|
+
readonly public: string
|
|
58
|
+
/** Nuxt srcDir (`/app/` by default) */
|
|
59
|
+
readonly app: string
|
|
60
|
+
/** Layouts directory (`/app/layouts` by default) */
|
|
61
|
+
readonly appLayouts: string
|
|
62
|
+
/** Middleware directory (`/app/middleware` by default) */
|
|
63
|
+
readonly appMiddleware: string
|
|
64
|
+
/** Pages directory (`/app/pages` by default) */
|
|
65
|
+
readonly appPages: string
|
|
66
|
+
/** Plugins directory (`/app/plugins` by default) */
|
|
67
|
+
readonly appPlugins: string
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Parameters
|
|
72
|
+
|
|
73
|
+
**`nuxt`** (optional): The Nuxt instance to get layers from. If not provided, the function will use the current Nuxt context.
|
|
74
|
+
|
|
75
|
+
### Return Value
|
|
76
|
+
|
|
77
|
+
The `getLayerDirectories` function returns an array of `LayerDirectories` objects, one for each layer in the application.
|
|
78
|
+
|
|
79
|
+
**Layer Priority Ordering**: The layers are ordered by priority, where:
|
|
80
|
+
- The **first layer** is the user/project layer (highest priority)
|
|
81
|
+
- **Earlier layers override later layers** in the array
|
|
82
|
+
- **Base layers appear last** in the array (lowest priority)
|
|
83
|
+
|
|
84
|
+
This ordering matches Nuxt's layer resolution system, where user-defined configurations and files take precedence over those from base layers.
|
|
85
|
+
|
|
86
|
+
**`LayerDirectories`**: An object containing the resolved directory paths for a layer.
|
|
87
|
+
|
|
88
|
+
| Property | Type | Description |
|
|
89
|
+
| --------------- | -------- | ------------------------------------------------------------------------------ |
|
|
90
|
+
| `root` | `string` | The root directory of the layer (equivalent to `rootDir`) |
|
|
91
|
+
| `server` | `string` | The server directory for Nitro server-side code |
|
|
92
|
+
| `modules` | `string` | The local modules directory |
|
|
93
|
+
| `shared` | `string` | The shared directory for code used by both client and server |
|
|
94
|
+
| `app` | `string` | The source directory of the layer (equivalent to `srcDir`) |
|
|
95
|
+
| `public` | `string` | The public directory for static assets |
|
|
96
|
+
| `appLayouts` | `string` | The layouts directory for Vue layout components |
|
|
97
|
+
| `appMiddleware` | `string` | The middleware directory for route middleware |
|
|
98
|
+
| `appPages` | `string` | The pages directory for file-based routing |
|
|
99
|
+
| `appPlugins` | `string` | The plugins directory for Nuxt plugins |
|
|
100
|
+
|
|
101
|
+
### Examples
|
|
102
|
+
|
|
103
|
+
**Processing files from all layers:**
|
|
104
|
+
|
|
105
|
+
```ts twoslash
|
|
106
|
+
// @errors: 2307
|
|
107
|
+
// ---cut---
|
|
108
|
+
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
|
|
109
|
+
import { resolve } from 'pathe'
|
|
110
|
+
import { globby } from 'globby'
|
|
111
|
+
|
|
112
|
+
export default defineNuxtModule({
|
|
113
|
+
async setup() {
|
|
114
|
+
const layerDirs = getLayerDirectories()
|
|
115
|
+
|
|
116
|
+
// Find all component files across layers
|
|
117
|
+
// Note: layerDirs[0] is the user layer (highest priority)
|
|
118
|
+
// Later layers in the array have lower priority
|
|
119
|
+
const componentFiles = []
|
|
120
|
+
for (const [index, layer] of layerDirs.entries()) {
|
|
121
|
+
const files = await globby('**/*.vue', {
|
|
122
|
+
cwd: resolve(layer.app, 'components'),
|
|
123
|
+
absolute: true
|
|
124
|
+
})
|
|
125
|
+
console.log(`Layer ${index} (${index === 0 ? 'user' : 'base'}):`, files.length, 'components')
|
|
126
|
+
componentFiles.push(...files)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Adding templates from multiple layers:**
|
|
133
|
+
|
|
134
|
+
```ts twoslash
|
|
135
|
+
import { defineNuxtModule, getLayerDirectories, addTemplate } from '@nuxt/kit'
|
|
136
|
+
import { resolve, basename } from 'pathe'
|
|
137
|
+
import { existsSync } from 'fs'
|
|
138
|
+
|
|
139
|
+
export default defineNuxtModule({
|
|
140
|
+
async setup() {
|
|
141
|
+
const layerDirs = getLayerDirectories()
|
|
142
|
+
|
|
143
|
+
// Add a config file from each layer that has one
|
|
144
|
+
for (const dirs of layerDirs) {
|
|
145
|
+
const configPath = resolve(dirs.app, 'my-module.config.ts')
|
|
146
|
+
if (existsSync(configPath)) {
|
|
147
|
+
addTemplate({
|
|
148
|
+
filename: `my-module-${basename(dirs.root)}.config.ts`,
|
|
149
|
+
src: configPath
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Respecting layer priority:**
|
|
158
|
+
|
|
159
|
+
```ts twoslash
|
|
160
|
+
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
|
|
161
|
+
import { resolve } from 'pathe'
|
|
162
|
+
import { existsSync, readFileSync } from 'fs'
|
|
163
|
+
|
|
164
|
+
export default defineNuxtModule({
|
|
165
|
+
setup() {
|
|
166
|
+
const layerDirs = getLayerDirectories()
|
|
167
|
+
|
|
168
|
+
// Find the first (highest priority) layer that has a specific config file
|
|
169
|
+
// This respects the layer priority system
|
|
170
|
+
let configContent = null
|
|
171
|
+
for (const dirs of layerDirs) {
|
|
172
|
+
const configPath = resolve(dirs.app, 'my-config.json')
|
|
173
|
+
if (existsSync(configPath)) {
|
|
174
|
+
configContent = readFileSync(configPath, 'utf-8')
|
|
175
|
+
console.log(`Using config from layer: ${dirs.root}`)
|
|
176
|
+
break // Use the first (highest priority) config found
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Alternative: Collect configs from all layers, with user layer taking precedence
|
|
181
|
+
const allConfigs = {}
|
|
182
|
+
for (const dirs of layerDirs.reverse()) { // Process from lowest to highest priority
|
|
183
|
+
const configPath = resolve(dirs.app, 'my-config.json')
|
|
184
|
+
if (existsSync(configPath)) {
|
|
185
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'))
|
|
186
|
+
Object.assign(allConfigs, config) // Later assignments override earlier ones
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Checking for layer-specific directories:**
|
|
194
|
+
|
|
195
|
+
```ts twoslash
|
|
196
|
+
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
|
|
197
|
+
import { existsSync } from 'fs'
|
|
198
|
+
import { resolve } from 'pathe'
|
|
199
|
+
|
|
200
|
+
export default defineNuxtModule({
|
|
201
|
+
setup() {
|
|
202
|
+
const layerDirs = getLayerDirectories()
|
|
203
|
+
|
|
204
|
+
// Find layers that have a specific custom directory
|
|
205
|
+
const layersWithAssets = layerDirs.filter(layer => {
|
|
206
|
+
return existsSync(resolve(layer.app, 'assets'))
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
console.log(`Found ${layersWithAssets.length} layers with assets directory`)
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
::note
|
|
215
|
+
The `getLayerDirectories` function includes caching via a WeakMap to avoid recomputing directory paths for the same layers repeatedly, improving performance when called multiple times.
|
|
216
|
+
::
|
|
217
|
+
|
|
218
|
+
::note
|
|
219
|
+
Directory paths returned by this function always include a trailing slash for consistency.
|
|
220
|
+
::
|
package/5.community/6.roadmap.md
CHANGED
|
@@ -59,17 +59,17 @@ We commit to support each major version of Nuxt for a minimum of six months afte
|
|
|
59
59
|
|
|
60
60
|
### Current Packages
|
|
61
61
|
|
|
62
|
-
The current active version of [Nuxt](https://nuxt.com) is **
|
|
62
|
+
The current active version of [Nuxt](https://nuxt.com) is **v4** which is available as `nuxt` on npm with the `latest` tag.
|
|
63
63
|
|
|
64
|
-
Nuxt
|
|
64
|
+
Nuxt 3 will continue to receive maintenance updates (both bug fixes and backports of features from Nuxt 4) until the end of January 2026.
|
|
65
65
|
|
|
66
66
|
Each active version has its own nightly releases which are generated automatically. For more about enabling the Nuxt nightly release channel, see [the nightly release channel docs](/docs/guide/going-further/nightly-release-channel).
|
|
67
67
|
|
|
68
|
-
Release
|
|
69
|
-
|
|
68
|
+
Release | | Initial release | End Of Life | Docs
|
|
69
|
+
-------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ---------------------------- | ---------------------------------------
|
|
70
70
|
**5.x** (scheduled) | | Q4 2025 (estimated) | TBA |
|
|
71
|
-
**4.x** (
|
|
72
|
-
**3.x** (
|
|
71
|
+
**4.x** (stable) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt latest version" src="https://flat.badgen.net/npm/v/nuxt?label=" class="not-prose"></a> | 2025-07-16 | 6 months after 5.x release | [nuxt.com](/docs/4.x)
|
|
72
|
+
**3.x** (maintenance) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 3.x version" src="https://flat.badgen.net/npm/v/nuxt/3x?label=" class="not-prose"></a> | 2022-11-16 | 2026-01-31 | [nuxt.com](/docs/3.x)
|
|
73
73
|
**2.x** (unsupported) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 2.x version" src="https://flat.badgen.net/npm/v/nuxt/2x?label=" class="not-prose"></a> | 2018-09-21 | 2024-06-30 | [v2.nuxt.com](https://v2.nuxt.com/docs)
|
|
74
74
|
**1.x** (unsupported) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 1.x version" src="https://flat.badgen.net/npm/v/nuxt/1x?label=" class="not-prose"></a> | 2018-01-08 | 2019-09-21 |
|
|
75
75
|
|