@nuxt/docs 4.0.3 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/1.getting-started/01.introduction.md +1 -1
- package/1.getting-started/03.configuration.md +2 -2
- package/1.getting-started/04.views.md +15 -15
- package/1.getting-started/05.assets.md +6 -6
- package/1.getting-started/06.styling.md +8 -8
- package/1.getting-started/07.routing.md +7 -7
- package/1.getting-started/08.seo-meta.md +9 -9
- package/1.getting-started/09.transitions.md +15 -15
- package/1.getting-started/10.data-fetching.md +9 -9
- package/1.getting-started/11.state-management.md +9 -9
- package/1.getting-started/12.error-handling.md +1 -1
- package/1.getting-started/14.layers.md +23 -2
- package/1.getting-started/15.prerendering.md +2 -2
- package/1.getting-started/17.testing.md +72 -19
- package/1.getting-started/18.upgrade.md +7 -7
- package/2.guide/1.concepts/1.auto-imports.md +6 -6
- package/2.guide/1.concepts/10.nuxt-lifecycle.md +6 -6
- package/2.guide/1.concepts/2.vuejs-development.md +3 -3
- package/2.guide/1.concepts/3.rendering.md +2 -2
- package/2.guide/1.concepts/8.typescript.md +1 -1
- package/2.guide/2.directory-structure/1.app/1.components.md +18 -18
- package/2.guide/2.directory-structure/1.app/1.composables.md +11 -11
- package/2.guide/2.directory-structure/1.app/1.layouts.md +7 -7
- package/2.guide/2.directory-structure/1.app/1.middleware.md +41 -3
- package/2.guide/2.directory-structure/1.app/1.pages.md +16 -16
- package/2.guide/2.directory-structure/1.app/1.plugins.md +7 -7
- package/2.guide/2.directory-structure/1.app/1.utils.md +3 -3
- package/2.guide/2.directory-structure/1.app/3.app-config.md +2 -2
- package/2.guide/2.directory-structure/1.app/3.app.md +12 -12
- package/2.guide/2.directory-structure/1.content.md +2 -2
- package/2.guide/2.directory-structure/1.public.md +1 -1
- package/2.guide/2.directory-structure/1.server.md +3 -3
- package/2.guide/2.directory-structure/1.shared.md +3 -3
- package/2.guide/2.directory-structure/2.nuxtrc.md +4 -0
- package/2.guide/3.going-further/1.experimental-features.md +38 -5
- package/2.guide/3.going-further/10.runtime-config.md +2 -2
- package/2.guide/3.going-further/2.hooks.md +1 -1
- package/2.guide/3.going-further/3.modules.md +50 -1
- package/2.guide/3.going-further/6.nuxt-app.md +2 -2
- package/2.guide/3.going-further/7.layers.md +34 -10
- package/2.guide/3.going-further/9.debugging.md +2 -1
- package/2.guide/4.recipes/1.custom-routing.md +1 -1
- package/2.guide/4.recipes/2.vite-plugin.md +1 -1
- package/2.guide/4.recipes/3.custom-usefetch.md +4 -4
- package/2.guide/4.recipes/4.sessions-and-authentication.md +4 -4
- package/2.guide/5.best-practices/performance.md +2 -2
- package/3.api/1.components/1.client-only.md +2 -2
- package/3.api/1.components/1.dev-only.md +1 -1
- package/3.api/1.components/1.nuxt-client-fallback.md +1 -1
- package/3.api/1.components/12.nuxt-route-announcer.md +2 -2
- package/3.api/1.components/2.nuxt-page.md +8 -8
- package/3.api/1.components/3.nuxt-layout.md +13 -13
- package/3.api/1.components/4.nuxt-link.md +9 -9
- package/3.api/1.components/5.nuxt-loading-indicator.md +2 -2
- package/3.api/1.components/7.nuxt-welcome.md +1 -1
- package/3.api/2.composables/on-prehydrate.md +1 -1
- package/3.api/2.composables/use-async-data.md +3 -3
- package/3.api/2.composables/use-cookie.md +1 -1
- package/3.api/2.composables/use-fetch.md +2 -2
- package/3.api/2.composables/use-lazy-async-data.md +1 -1
- package/3.api/2.composables/use-lazy-fetch.md +1 -1
- package/3.api/2.composables/use-nuxt-app.md +7 -7
- package/3.api/2.composables/use-nuxt-data.md +4 -4
- package/3.api/2.composables/use-preview-mode.md +1 -1
- package/3.api/2.composables/use-request-fetch.md +1 -1
- package/3.api/2.composables/use-request-header.md +1 -1
- package/3.api/2.composables/use-request-headers.md +1 -1
- package/3.api/2.composables/use-request-url.md +1 -1
- package/3.api/2.composables/use-response-header.md +3 -3
- package/3.api/2.composables/use-route-announcer.md +1 -1
- package/3.api/2.composables/use-route.md +37 -2
- package/3.api/2.composables/use-router.md +5 -5
- package/3.api/2.composables/use-runtime-config.md +1 -1
- package/3.api/2.composables/use-seo-meta.md +3 -3
- package/3.api/2.composables/use-server-seo-meta.md +1 -1
- package/3.api/3.utils/$fetch.md +4 -4
- package/3.api/3.utils/abort-navigation.md +4 -4
- package/3.api/3.utils/add-route-middleware.md +5 -5
- package/3.api/3.utils/call-once.md +2 -2
- package/3.api/3.utils/create-error.md +1 -1
- package/3.api/3.utils/define-nuxt-component.md +2 -2
- package/3.api/3.utils/define-nuxt-route-middleware.md +3 -3
- package/3.api/3.utils/define-page-meta.md +12 -12
- package/3.api/3.utils/define-route-rules.md +1 -1
- package/3.api/3.utils/navigate-to.md +1 -1
- package/3.api/3.utils/on-nuxt-ready.md +1 -1
- package/3.api/3.utils/refresh-cookie.md +1 -1
- package/3.api/3.utils/refresh-nuxt-data.md +2 -2
- package/3.api/3.utils/set-page-layout.md +1 -1
- package/3.api/4.commands/add.md +7 -7
- package/3.api/4.commands/init.md +2 -1
- package/3.api/5.kit/1.modules.md +68 -0
- package/3.api/5.kit/16.layers.md +220 -0
- package/3.api/5.kit/7.pages.md +1 -1
- package/3.api/5.kit/8.layout.md +1 -1
- package/3.api/5.kit/9.plugins.md +1 -1
- package/3.api/6.nuxt-config.md +22 -19
- package/5.community/6.roadmap.md +6 -6
- package/6.bridge/4.plugins-and-middleware.md +3 -3
- package/6.bridge/6.meta.md +1 -1
- package/7.migration/2.configuration.md +2 -2
- package/7.migration/3.auto-imports.md +1 -1
- package/7.migration/5.plugins-and-middleware.md +2 -2
- package/7.migration/6.pages-and-layouts.md +8 -8
- package/7.migration/7.component-options.md +4 -4
- package/7.migration/8.runtime-config.md +1 -1
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ pnpm create nuxt -t module my-module
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
```bash [bun]
|
|
31
|
-
bun create nuxt -t module my-module
|
|
31
|
+
bun create nuxt -- -t module my-module
|
|
32
32
|
```
|
|
33
33
|
::
|
|
34
34
|
|
|
@@ -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
|
// ...
|
|
@@ -763,6 +780,38 @@ Nuxt Modules should provide an explicit prefix for any exposed configuration, pl
|
|
|
763
780
|
|
|
764
781
|
Ideally, you should prefix them with your module's name (e.g. if your module is called `nuxt-foo`, expose `<FooButton>` and `useFooBar()` and **not** `<Button>` and `useBar()`).
|
|
765
782
|
|
|
783
|
+
#### Use Lifecycle Hooks for One-Time Setup
|
|
784
|
+
|
|
785
|
+
When your module needs to perform one-time setup tasks (like generating configuration files, setting up databases, or installing dependencies), use lifecycle hooks instead of running the logic in your main `setup` function.
|
|
786
|
+
|
|
787
|
+
```ts
|
|
788
|
+
import { addServerHandler, defineNuxtModule } from 'nuxt/kit'
|
|
789
|
+
import semver from 'semver'
|
|
790
|
+
|
|
791
|
+
export default defineNuxtModule({
|
|
792
|
+
meta: {
|
|
793
|
+
name: 'my-database-module',
|
|
794
|
+
version: '1.0.0',
|
|
795
|
+
},
|
|
796
|
+
async onInstall (nuxt) {
|
|
797
|
+
// One-time setup: create database schema, generate config files, etc.
|
|
798
|
+
await generateDatabaseConfig(nuxt.options.rootDir)
|
|
799
|
+
},
|
|
800
|
+
async onUpgrade (options, nuxt, previousVersion) {
|
|
801
|
+
// Handle version-specific migrations
|
|
802
|
+
if (semver.lt(previousVersion, '1.0.0')) {
|
|
803
|
+
await migrateLegacyData()
|
|
804
|
+
}
|
|
805
|
+
},
|
|
806
|
+
setup (options, nuxt) {
|
|
807
|
+
// Regular setup logic that runs on every build
|
|
808
|
+
addServerHandler({ /* ... */ })
|
|
809
|
+
},
|
|
810
|
+
})
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
This pattern prevents unnecessary work on every build and provides a better developer experience. See the [lifecycle hooks documentation](/docs/api/kit/modules#using-lifecycle-hooks-for-module-installation-and-upgrade) for more details.
|
|
814
|
+
|
|
766
815
|
#### Be TypeScript Friendly
|
|
767
816
|
|
|
768
817
|
Nuxt has first-class TypeScript integration for the best developer experience.
|
|
@@ -23,7 +23,7 @@ Jump over the `NuxtApp` interface documentation.
|
|
|
23
23
|
|
|
24
24
|
Many composables and utilities, both built-in and user-made, may require access to the Nuxt instance. This doesn't exist everywhere on your application, because a fresh instance is created on every request.
|
|
25
25
|
|
|
26
|
-
Currently, the Nuxt context is only accessible in [plugins](/docs/guide/directory-structure/plugins), [Nuxt hooks](/docs/guide/going-further/hooks), [Nuxt middleware](/docs/guide/directory-structure/middleware) (if wrapped in `defineNuxtRouteMiddleware`), and [setup functions](https://vuejs.org/api/composition-api-setup.html) (in pages and components).
|
|
26
|
+
Currently, the Nuxt context is only accessible in [plugins](/docs/guide/directory-structure/plugins), [Nuxt hooks](/docs/guide/going-further/hooks), [Nuxt middleware](/docs/guide/directory-structure/app/middleware) (if wrapped in `defineNuxtRouteMiddleware`), and [setup functions](https://vuejs.org/api/composition-api-setup.html) (in pages and components).
|
|
27
27
|
|
|
28
28
|
If a composable is called without access to the context, you may get an error stating that 'A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function.' In that case, you can also explicitly call functions within this context by using [`nuxtApp.runWithContext`](/docs/api/composables/use-nuxt-app#runwithcontext).
|
|
29
29
|
|
|
@@ -31,7 +31,7 @@ If a composable is called without access to the context, you may get an error st
|
|
|
31
31
|
|
|
32
32
|
Within composables, plugins and components you can access `nuxtApp` with [`useNuxtApp()`](/docs/api/composables/use-nuxt-app):
|
|
33
33
|
|
|
34
|
-
```ts [composables/useMyComposable.ts]
|
|
34
|
+
```ts [app/composables/useMyComposable.ts]
|
|
35
35
|
export function useMyComposable () {
|
|
36
36
|
const nuxtApp = useNuxtApp()
|
|
37
37
|
// access runtime nuxt app instance
|
|
@@ -15,15 +15,16 @@ export default defineNuxtConfig({})
|
|
|
15
15
|
|
|
16
16
|
Additionally, certain other files in the layer directory will be auto-scanned and used by Nuxt for the project extending this layer.
|
|
17
17
|
|
|
18
|
-
- [`components/*`](/docs/guide/directory-structure/components) - Extend the default components
|
|
19
|
-
- [`composables/*`](/docs/guide/directory-structure/composables) - Extend the default composables
|
|
20
|
-
- [`layouts/*`](/docs/guide/directory-structure/layouts) - Extend the default layouts
|
|
21
|
-
- [`
|
|
22
|
-
- [`
|
|
18
|
+
- [`app/components/*`](/docs/guide/directory-structure/app/components) - Extend the default components
|
|
19
|
+
- [`app/composables/*`](/docs/guide/directory-structure/app/composables) - Extend the default composables
|
|
20
|
+
- [`app/layouts/*`](/docs/guide/directory-structure/app/layouts) - Extend the default layouts
|
|
21
|
+
- [`app/middleware/*`](/docs/guide/directory-structure/app/middleware) - Extend the default middleware
|
|
22
|
+
- [`app/pages/*`](/docs/guide/directory-structure/app/pages) - Extend the default pages
|
|
23
|
+
- [`app/plugins/*`](/docs/guide/directory-structure/plugins) - Extend the default plugins
|
|
24
|
+
- [`app/utils/*`](/docs/guide/directory-structure/app/utils) - Extend the default utils
|
|
25
|
+
- [`app/app.config.ts`](/docs/guide/directory-structure/app-config) - Extend the default app config
|
|
23
26
|
- [`server/*`](/docs/guide/directory-structure/server) - Extend the default server endpoints & middleware
|
|
24
|
-
- [`utils/*`](/docs/guide/directory-structure/utils) - Extend the default utils
|
|
25
27
|
- [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config)- Extend the default nuxt config
|
|
26
|
-
- [`app.config.ts`](/docs/guide/directory-structure/app-config) - Extend the default app config
|
|
27
28
|
|
|
28
29
|
## Basic Example
|
|
29
30
|
|
|
@@ -37,7 +38,7 @@ Additionally, certain other files in the layer directory will be auto-scanned an
|
|
|
37
38
|
})
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
```vue [app.vue]
|
|
41
|
+
```vue [app/app.vue]
|
|
41
42
|
<template>
|
|
42
43
|
<BaseComponent/>
|
|
43
44
|
</template>
|
|
@@ -57,7 +58,7 @@ Additionally, certain other files in the layer directory will be auto-scanned an
|
|
|
57
58
|
})
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
```vue [base/components/BaseComponent.vue]
|
|
61
|
+
```vue [base/app/components/BaseComponent.vue]
|
|
61
62
|
<template>
|
|
62
63
|
<h1>Extending Components is Fun!</h1>
|
|
63
64
|
</template>
|
|
@@ -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:
|
|
@@ -194,7 +218,7 @@ const currentDir = dirname(fileURLToPath(import.meta.url))
|
|
|
194
218
|
|
|
195
219
|
export default defineNuxtConfig({
|
|
196
220
|
css: [
|
|
197
|
-
join(currentDir, './assets/main.css')
|
|
221
|
+
join(currentDir, './app/assets/main.css')
|
|
198
222
|
]
|
|
199
223
|
})
|
|
200
224
|
```
|
|
@@ -49,7 +49,8 @@ You may need to update the config below with a path to your web browser. For mor
|
|
|
49
49
|
"request": "launch",
|
|
50
50
|
"name": "client: chrome",
|
|
51
51
|
"url": "http://localhost:3000",
|
|
52
|
-
|
|
52
|
+
// this should point to your Nuxt `srcDir`, which is `app` by default
|
|
53
|
+
"webRoot": "${workspaceFolder}/app"
|
|
53
54
|
},
|
|
54
55
|
{
|
|
55
56
|
"type": "node",
|
|
@@ -5,7 +5,7 @@ description: "In Nuxt, your routing is defined by the structure of your files in
|
|
|
5
5
|
|
|
6
6
|
## Adding custom routes
|
|
7
7
|
|
|
8
|
-
In Nuxt, your routing is defined by the structure of your files inside the [pages directory](/docs/guide/directory-structure/pages). However, since it uses [vue-router](https://router.vuejs.org) under the hood, Nuxt offers you several ways to add custom routes in your project.
|
|
8
|
+
In Nuxt, your routing is defined by the structure of your files inside the [app/pages directory](/docs/guide/directory-structure/app/pages). However, since it uses [vue-router](https://router.vuejs.org) under the hood, Nuxt offers you several ways to add custom routes in your project.
|
|
9
9
|
|
|
10
10
|
### Router Config
|
|
11
11
|
|
|
@@ -52,7 +52,7 @@ For example, we can have a `config.yaml` that stores configuration data and impo
|
|
|
52
52
|
greeting: "Hello, Nuxt with Vite!"
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
```vue [components/Hello.vue]
|
|
55
|
+
```vue [app/components/Hello.vue]
|
|
56
56
|
<script setup>
|
|
57
57
|
import config from '~/data/hello.yaml'
|
|
58
58
|
</script>
|
|
@@ -23,7 +23,7 @@ Let's pretend here that:
|
|
|
23
23
|
- We are storing the JWT token in a session with [nuxt-auth-utils](https://github.com/atinux/nuxt-auth-utils)
|
|
24
24
|
- If the API responds with a `401` status code, we redirect the user to the `/login` page
|
|
25
25
|
|
|
26
|
-
```ts [plugins/api.ts]
|
|
26
|
+
```ts [app/plugins/api.ts]
|
|
27
27
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
28
28
|
const { session } = useUserSession()
|
|
29
29
|
|
|
@@ -53,7 +53,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
53
53
|
|
|
54
54
|
With this Nuxt plugin, `$api` is exposed from `useNuxtApp()` to make API calls directly from the Vue components:
|
|
55
55
|
|
|
56
|
-
```vue [app.vue]
|
|
56
|
+
```vue [app/app.vue]
|
|
57
57
|
<script setup>
|
|
58
58
|
const { $api } = useNuxtApp()
|
|
59
59
|
const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
|
|
@@ -68,7 +68,7 @@ Wrapping with [`useAsyncData`](/docs/api/composables/use-async-data) **avoid dou
|
|
|
68
68
|
|
|
69
69
|
Now that `$api` has the logic we want, let's create a `useAPI` composable to replace the usage of `useAsyncData` + `$api`:
|
|
70
70
|
|
|
71
|
-
```ts [composables/useAPI.ts]
|
|
71
|
+
```ts [app/composables/useAPI.ts]
|
|
72
72
|
import type { UseFetchOptions } from 'nuxt/app'
|
|
73
73
|
|
|
74
74
|
export function useAPI<T>(
|
|
@@ -84,7 +84,7 @@ export function useAPI<T>(
|
|
|
84
84
|
|
|
85
85
|
Let's use the new composable and have a nice and clean component:
|
|
86
86
|
|
|
87
|
-
```vue [app.vue]
|
|
87
|
+
```vue [app/app.vue]
|
|
88
88
|
<script setup>
|
|
89
89
|
const { data: modules } = await useAPI('/modules')
|
|
90
90
|
</script>
|
|
@@ -91,7 +91,7 @@ const { loggedIn, session, user, clear, fetch } = useUserSession()
|
|
|
91
91
|
|
|
92
92
|
Let's create a login page with a form to submit the login data to our `/api/login` route.
|
|
93
93
|
|
|
94
|
-
```vue [pages/login.vue]
|
|
94
|
+
```vue [app/pages/login.vue]
|
|
95
95
|
<script setup lang="ts">
|
|
96
96
|
const { loggedIn, user, fetch: refreshSession } = useUserSession()
|
|
97
97
|
const credentials = reactive({
|
|
@@ -143,13 +143,13 @@ export default defineEventHandler(async (event) => {
|
|
|
143
143
|
|
|
144
144
|
## Protect App Routes
|
|
145
145
|
|
|
146
|
-
Our data is safe with the server-side route in place, but without doing anything else, unauthenticated users would probably get some odd data when trying to access the `/users` page. We should create a [client-side middleware](https://nuxt.com/docs/guide/directory-structure/middleware) to protect the route on the client side and redirect users to the login page.
|
|
146
|
+
Our data is safe with the server-side route in place, but without doing anything else, unauthenticated users would probably get some odd data when trying to access the `/users` page. We should create a [client-side middleware](https://nuxt.com/docs/guide/directory-structure/app/middleware) to protect the route on the client side and redirect users to the login page.
|
|
147
147
|
|
|
148
148
|
`nuxt-auth-utils` provides a convenient `useUserSession` composable which we'll use to check if the user is logged in, and redirect them if they are not.
|
|
149
149
|
|
|
150
150
|
We'll create a middleware in the `/middleware` directory. Unlike on the server, client-side middleware is not automatically applied to all endpoints, and we'll need to specify where we want it applied.
|
|
151
151
|
|
|
152
|
-
```typescript [middleware/authenticated.ts]
|
|
152
|
+
```typescript [app/middleware/authenticated.ts]
|
|
153
153
|
export default defineNuxtRouteMiddleware(() => {
|
|
154
154
|
const { loggedIn } = useUserSession()
|
|
155
155
|
|
|
@@ -166,7 +166,7 @@ Now that we have our app middleware to protect our routes, we can use it on our
|
|
|
166
166
|
|
|
167
167
|
We'll use [`definePageMeta`](/docs/api/utils/define-page-meta) to apply the middleware to the route that we want to protect.
|
|
168
168
|
|
|
169
|
-
```vue [pages/index.vue]
|
|
169
|
+
```vue [app/pages/index.vue]
|
|
170
170
|
<script setup lang="ts">
|
|
171
171
|
definePageMeta({
|
|
172
172
|
middleware: ['authenticated'],
|
|
@@ -90,7 +90,7 @@ const show = ref(false)
|
|
|
90
90
|
|
|
91
91
|
By using the Lazy prefix you can delay loading the component code until the right moment, which can be helpful for optimizing your JavaScript bundle size.
|
|
92
92
|
|
|
93
|
-
:read-more{title="Lazy loading components" to="/docs/guide/directory-structure/components#dynamic-imports"}
|
|
93
|
+
:read-more{title="Lazy loading components" to="/docs/guide/directory-structure/app/components#dynamic-imports"}
|
|
94
94
|
|
|
95
95
|
### Lazy Hydration
|
|
96
96
|
|
|
@@ -106,7 +106,7 @@ It is not always necessary to hydrate (or make interactive) all the components o
|
|
|
106
106
|
|
|
107
107
|
To optimize your app, you may want to delay the hydration of some components until they're visible, or until the browser is done with more important tasks.
|
|
108
108
|
|
|
109
|
-
:read-more{title="Lazy hydration" to="/docs/guide/directory-structure/components#delayed-or-lazy-hydration"}
|
|
109
|
+
:read-more{title="Lazy hydration" to="/docs/guide/directory-structure/app/components#delayed-or-lazy-hydration"}
|
|
110
110
|
|
|
111
111
|
### Fetching data
|
|
112
112
|
|
|
@@ -35,7 +35,7 @@ The content of the default slot will be tree-shaken out of the server build. (Th
|
|
|
35
35
|
|
|
36
36
|
- `#fallback`: specify a content to be rendered on the server and displayed until `<ClientOnly>` is mounted in the browser.
|
|
37
37
|
|
|
38
|
-
```vue [pages/example.vue]
|
|
38
|
+
```vue [app/pages/example.vue]
|
|
39
39
|
<template>
|
|
40
40
|
<div>
|
|
41
41
|
<Sidebar />
|
|
@@ -58,7 +58,7 @@ The content of the default slot will be tree-shaken out of the server build. (Th
|
|
|
58
58
|
|
|
59
59
|
Components inside `<ClientOnly>` are rendered only after being mounted. To access the rendered elements in the DOM, you can watch a template ref:
|
|
60
60
|
|
|
61
|
-
```vue [pages/example.vue]
|
|
61
|
+
```vue [app/pages/example.vue]
|
|
62
62
|
<script setup lang="ts">
|
|
63
63
|
const nuxtWelcomeRef = useTemplateRef('nuxtWelcomeRef')
|
|
64
64
|
|
|
@@ -18,7 +18,7 @@ Nuxt provides the `<NuxtClientFallback>` component to render its content on the
|
|
|
18
18
|
This component is experimental and in order to use it you must enable the `experimental.clientFallback` option in your `nuxt.config`.
|
|
19
19
|
::
|
|
20
20
|
|
|
21
|
-
```vue [pages/example.vue]
|
|
21
|
+
```vue [app/pages/example.vue]
|
|
22
22
|
<template>
|
|
23
23
|
<div>
|
|
24
24
|
<Sidebar />
|
|
@@ -16,9 +16,9 @@ This component is available in Nuxt v3.12+.
|
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
|
-
Add `<NuxtRouteAnnouncer/>` in your [`app.vue`](/docs/guide/directory-structure/app) or [`layouts/`](/docs/guide/directory-structure/layouts) to enhance accessibility by informing assistive technologies about page title changes. This ensures that navigational changes are announced to users relying on screen readers.
|
|
19
|
+
Add `<NuxtRouteAnnouncer/>` in your [`app.vue`](/docs/guide/directory-structure/app) or [`app/layouts/`](/docs/guide/directory-structure/app/layouts) to enhance accessibility by informing assistive technologies about page title changes. This ensures that navigational changes are announced to users relying on screen readers.
|
|
20
20
|
|
|
21
|
-
```vue [app.vue]
|
|
21
|
+
```vue [app/app.vue]
|
|
22
22
|
<template>
|
|
23
23
|
<NuxtRouteAnnouncer />
|
|
24
24
|
<NuxtLayout>
|
|
@@ -8,7 +8,7 @@ links:
|
|
|
8
8
|
size: xs
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
`<NuxtPage>` is a built-in component that comes with Nuxt. It lets you display top-level or nested pages located in the [`pages/`](/docs/guide/directory-structure/pages) directory.
|
|
11
|
+
`<NuxtPage>` is a built-in component that comes with Nuxt. It lets you display top-level or nested pages located in the [`app/pages/`](/docs/guide/directory-structure/app/pages) directory.
|
|
12
12
|
|
|
13
13
|
::note
|
|
14
14
|
`<NuxtPage>` is a wrapper around [`<RouterView>`](https://router.vuejs.org/api/interfaces/RouterViewProps.html#interface-routerviewprops) from Vue Router. It should be used instead of `<RouterView>` because the former takes additional care of internal states. Otherwise, `useRoute()` may return incorrect paths.
|
|
@@ -63,7 +63,7 @@ Nuxt automatically resolves the `name` and `route` by scanning and rendering all
|
|
|
63
63
|
|
|
64
64
|
For example, if you pass a key that never changes, the `<NuxtPage>` component will be rendered only once - when it is first mounted.
|
|
65
65
|
|
|
66
|
-
```vue [app.vue]
|
|
66
|
+
```vue [app/app.vue]
|
|
67
67
|
<template>
|
|
68
68
|
<NuxtPage page-key="static" />
|
|
69
69
|
</template>
|
|
@@ -81,7 +81,7 @@ Don't use `$route` object here as it can cause problems with how `<NuxtPage>` re
|
|
|
81
81
|
|
|
82
82
|
Alternatively, `pageKey` can be passed as a `key` value via [`definePageMeta`](/docs/api/utils/define-page-meta) from the `<script>` section of your Vue component in the `/pages` directory.
|
|
83
83
|
|
|
84
|
-
```vue [pages/my-page.vue]
|
|
84
|
+
```vue [app/pages/my-page.vue]
|
|
85
85
|
<script setup lang="ts">
|
|
86
86
|
definePageMeta({
|
|
87
87
|
key: route => route.fullPath
|
|
@@ -95,7 +95,7 @@ definePageMeta({
|
|
|
95
95
|
|
|
96
96
|
To get the `ref` of a page component, access it through `ref.value.pageRef`
|
|
97
97
|
|
|
98
|
-
````vue [app.vue]
|
|
98
|
+
````vue [app/app.vue]
|
|
99
99
|
<script setup lang="ts">
|
|
100
100
|
const page = ref()
|
|
101
101
|
|
|
@@ -127,7 +127,7 @@ defineExpose({
|
|
|
127
127
|
|
|
128
128
|
For example, in the below example, the value of `foobar` will be passed to the `NuxtPage` component and then to the page components.
|
|
129
129
|
|
|
130
|
-
```vue [app.vue]
|
|
130
|
+
```vue [app/app.vue]
|
|
131
131
|
<template>
|
|
132
132
|
<NuxtPage :foobar="123" />
|
|
133
133
|
</template>
|
|
@@ -135,7 +135,7 @@ For example, in the below example, the value of `foobar` will be passed to the `
|
|
|
135
135
|
|
|
136
136
|
We can access the `foobar` prop in the page component:
|
|
137
137
|
|
|
138
|
-
```vue [pages/page.vue]
|
|
138
|
+
```vue [app/pages/page.vue]
|
|
139
139
|
<script setup lang="ts">
|
|
140
140
|
const props = defineProps<{ foobar: number }>()
|
|
141
141
|
|
|
@@ -144,11 +144,11 @@ console.log(props.foobar) // Outputs: 123
|
|
|
144
144
|
|
|
145
145
|
If you have not defined the prop with `defineProps`, any props passed down to `NuxtPage` can still be accessed directly from the page `attrs`:
|
|
146
146
|
|
|
147
|
-
```vue [pages/page.vue]
|
|
147
|
+
```vue [app/pages/page.vue]
|
|
148
148
|
<script setup lang="ts">
|
|
149
149
|
const attrs = useAttrs()
|
|
150
150
|
console.log(attrs.foobar) // Outputs: 123
|
|
151
151
|
</script>
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
:read-more{to="/docs/guide/directory-structure/pages"}
|
|
154
|
+
:read-more{to="/docs/guide/directory-structure/app/pages"}
|
|
@@ -10,7 +10,7 @@ links:
|
|
|
10
10
|
|
|
11
11
|
You can use `<NuxtLayout />` component to activate the `default` layout on `app.vue` or `error.vue`.
|
|
12
12
|
|
|
13
|
-
```vue [app.vue]
|
|
13
|
+
```vue [app/app.vue]
|
|
14
14
|
<template>
|
|
15
15
|
<NuxtLayout>
|
|
16
16
|
some page content
|
|
@@ -18,15 +18,15 @@ You can use `<NuxtLayout />` component to activate the `default` layout on `app.
|
|
|
18
18
|
</template>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
:read-more{to="/docs/guide/directory-structure/layouts"}
|
|
21
|
+
:read-more{to="/docs/guide/directory-structure/app/layouts"}
|
|
22
22
|
|
|
23
23
|
## Props
|
|
24
24
|
|
|
25
|
-
- `name`: Specify a layout name to be rendered, can be a string, reactive reference or a computed property. It **must** match the name of the corresponding layout file in the [`layouts/`](/docs/guide/directory-structure/layouts) directory.
|
|
25
|
+
- `name`: Specify a layout name to be rendered, can be a string, reactive reference or a computed property. It **must** match the name of the corresponding layout file in the [`app/layouts/`](/docs/guide/directory-structure/app/layouts) directory.
|
|
26
26
|
- **type**: `string`
|
|
27
27
|
- **default**: `default`
|
|
28
28
|
|
|
29
|
-
```vue [pages/index.vue]
|
|
29
|
+
```vue [app/pages/index.vue]
|
|
30
30
|
<script setup lang="ts">
|
|
31
31
|
// layouts/custom.vue
|
|
32
32
|
const layout = 'custom'
|
|
@@ -51,11 +51,11 @@ Please note the layout name is normalized to kebab-case, so if your layout file
|
|
|
51
51
|
</template>
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
::read-more{to="/docs/guide/directory-structure/layouts"}
|
|
54
|
+
::read-more{to="/docs/guide/directory-structure/app/layouts"}
|
|
55
55
|
Read more about dynamic layouts.
|
|
56
56
|
::
|
|
57
57
|
|
|
58
|
-
- `fallback`: If an invalid layout is passed to the `name` prop, no layout will be rendered. Specify a `fallback` layout to be rendered in this scenario. It **must** match the name of the corresponding layout file in the [`layouts/`](/docs/guide/directory-structure/layouts) directory.
|
|
58
|
+
- `fallback`: If an invalid layout is passed to the `name` prop, no layout will be rendered. Specify a `fallback` layout to be rendered in this scenario. It **must** match the name of the corresponding layout file in the [`app/layouts/`](/docs/guide/directory-structure/app/layouts) directory.
|
|
59
59
|
- **type**: `string`
|
|
60
60
|
- **default**: `null`
|
|
61
61
|
|
|
@@ -63,7 +63,7 @@ Read more about dynamic layouts.
|
|
|
63
63
|
|
|
64
64
|
`NuxtLayout` also accepts any additional props that you may need to pass to the layout. These custom props are then made accessible as attributes.
|
|
65
65
|
|
|
66
|
-
```vue [pages/some-page.vue]
|
|
66
|
+
```vue [app/pages/some-page.vue]
|
|
67
67
|
<template>
|
|
68
68
|
<div>
|
|
69
69
|
<NuxtLayout name="custom" title="I am a custom layout">
|
|
@@ -75,7 +75,7 @@ Read more about dynamic layouts.
|
|
|
75
75
|
|
|
76
76
|
In the above example, the value of `title` will be available using `$attrs.title` in the template or `useAttrs().title` in `<script setup>` at custom.vue.
|
|
77
77
|
|
|
78
|
-
```vue [layouts/custom.vue]
|
|
78
|
+
```vue [app/layouts/custom.vue]
|
|
79
79
|
<script setup lang="ts">
|
|
80
80
|
const layoutCustomProps = useAttrs()
|
|
81
81
|
|
|
@@ -89,7 +89,7 @@ console.log(layoutCustomProps.title) // I am a custom layout
|
|
|
89
89
|
|
|
90
90
|
::code-group
|
|
91
91
|
|
|
92
|
-
```vue [pages/index.vue]
|
|
92
|
+
```vue [app/pages/index.vue]
|
|
93
93
|
<template>
|
|
94
94
|
<div>
|
|
95
95
|
<NuxtLayout name="custom">
|
|
@@ -99,7 +99,7 @@ console.log(layoutCustomProps.title) // I am a custom layout
|
|
|
99
99
|
</template>
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
```vue [layouts/custom.vue]
|
|
102
|
+
```vue [app/layouts/custom.vue]
|
|
103
103
|
<template>
|
|
104
104
|
<div>
|
|
105
105
|
<!-- named slot -->
|
|
@@ -119,7 +119,7 @@ To get the ref of a layout component, access it through `ref.value.layoutRef`.
|
|
|
119
119
|
|
|
120
120
|
::code-group
|
|
121
121
|
|
|
122
|
-
```vue [app.vue]
|
|
122
|
+
```vue [app/app.vue]
|
|
123
123
|
<script setup lang="ts">
|
|
124
124
|
const layout = ref()
|
|
125
125
|
|
|
@@ -135,7 +135,7 @@ function logFoo () {
|
|
|
135
135
|
</template>
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
```vue [layouts/default.vue]
|
|
138
|
+
```vue [app/layouts/default.vue]
|
|
139
139
|
<script setup lang="ts">
|
|
140
140
|
const foo = () => console.log('foo')
|
|
141
141
|
defineExpose({
|
|
@@ -153,4 +153,4 @@ defineExpose({
|
|
|
153
153
|
|
|
154
154
|
::
|
|
155
155
|
|
|
156
|
-
:read-more{to="/docs/guide/directory-structure/layouts"}
|
|
156
|
+
:read-more{to="/docs/guide/directory-structure/app/layouts"}
|
|
@@ -17,7 +17,7 @@ links:
|
|
|
17
17
|
In this example, we use `<NuxtLink>` component to link to another page of the application.
|
|
18
18
|
|
|
19
19
|
::code-group
|
|
20
|
-
```vue [pages/index.vue]
|
|
20
|
+
```vue [app/pages/index.vue]
|
|
21
21
|
<template>
|
|
22
22
|
<NuxtLink to="/about">About page</NuxtLink>
|
|
23
23
|
</template>
|
|
@@ -34,7 +34,7 @@ In this example, we use `<NuxtLink>` component to link to another page of the ap
|
|
|
34
34
|
In this example, we pass the `id` param to link to the route `~/pages/posts/[id].vue`.
|
|
35
35
|
|
|
36
36
|
::code-group
|
|
37
|
-
```vue [pages/index.vue]
|
|
37
|
+
```vue [app/pages/index.vue]
|
|
38
38
|
<template>
|
|
39
39
|
<NuxtLink :to="{ name: 'posts-id', params: { id: 123 } }">
|
|
40
40
|
Post 123
|
|
@@ -65,7 +65,7 @@ The `external` prop explicitly indicates that the link is external. `<NuxtLink>`
|
|
|
65
65
|
|
|
66
66
|
For static files in the `/public` directory, such as PDFs or images, use the `external` prop to ensure the link resolves correctly.
|
|
67
67
|
|
|
68
|
-
```vue [pages/index.vue]
|
|
68
|
+
```vue [app/pages/index.vue]
|
|
69
69
|
<template>
|
|
70
70
|
<NuxtLink to="/example-report.pdf" external>
|
|
71
71
|
Download Report
|
|
@@ -77,7 +77,7 @@ For static files in the `/public` directory, such as PDFs or images, use the `ex
|
|
|
77
77
|
|
|
78
78
|
When pointing to a different application on the same domain, using the `external` prop ensures the correct behavior.
|
|
79
79
|
|
|
80
|
-
```vue [pages/index.vue]
|
|
80
|
+
```vue [app/pages/index.vue]
|
|
81
81
|
<template>
|
|
82
82
|
<NuxtLink to="/another-app" external>
|
|
83
83
|
Go to Another App
|
|
@@ -91,7 +91,7 @@ Using the `external` prop or relying on automatic handling ensures proper naviga
|
|
|
91
91
|
|
|
92
92
|
In this example, we use `<NuxtLink>` component to link to a website.
|
|
93
93
|
|
|
94
|
-
```vue [app.vue]
|
|
94
|
+
```vue [app/app.vue]
|
|
95
95
|
<template>
|
|
96
96
|
<NuxtLink to="https://nuxtjs.org">
|
|
97
97
|
Nuxt website
|
|
@@ -110,7 +110,7 @@ These defaults have no negative impact on SEO and are considered [best practice]
|
|
|
110
110
|
|
|
111
111
|
When you need to overwrite this behavior you can use the `rel` or `noRel` props.
|
|
112
112
|
|
|
113
|
-
```vue [app.vue]
|
|
113
|
+
```vue [app/app.vue]
|
|
114
114
|
<template>
|
|
115
115
|
<NuxtLink to="https://twitter.com/nuxt_js">
|
|
116
116
|
Nuxt Twitter
|
|
@@ -129,7 +129,7 @@ When you need to overwrite this behavior you can use the `rel` or `noRel` props.
|
|
|
129
129
|
|
|
130
130
|
A `noRel` prop can be used to prevent the default `rel` attribute from being added to the absolute links.
|
|
131
131
|
|
|
132
|
-
```vue [app.vue]
|
|
132
|
+
```vue [app/app.vue]
|
|
133
133
|
<template>
|
|
134
134
|
<NuxtLink to="https://github.com/nuxt" no-rel>
|
|
135
135
|
Nuxt GitHub
|
|
@@ -146,7 +146,7 @@ A `noRel` prop can be used to prevent the default `rel` attribute from being add
|
|
|
146
146
|
|
|
147
147
|
Nuxt automatically includes smart prefetching. That means it detects when a link is visible (by default), either in the viewport or when scrolling and prefetches the JavaScript for those pages so that they are ready when the user clicks the link. Nuxt only loads the resources when the browser isn't busy and skips prefetching if your connection is offline or if you only have 2g connection.
|
|
148
148
|
|
|
149
|
-
```vue [pages/index.vue]
|
|
149
|
+
```vue [app/pages/index.vue]
|
|
150
150
|
<NuxtLink to="/about" no-prefetch>About page not pre-fetched</NuxtLink>
|
|
151
151
|
<NuxtLink to="/about" :prefetch="false">About page not pre-fetched</NuxtLink>
|
|
152
152
|
```
|
|
@@ -286,7 +286,7 @@ export default defineNuxtConfig({
|
|
|
286
286
|
|
|
287
287
|
You can overwrite `<NuxtLink>` defaults by creating your own link component using `defineNuxtLink`.
|
|
288
288
|
|
|
289
|
-
```js [components/MyNuxtLink.ts]
|
|
289
|
+
```js [app/components/MyNuxtLink.ts]
|
|
290
290
|
export default defineNuxtLink({
|
|
291
291
|
componentName: 'MyNuxtLink',
|
|
292
292
|
/* see signature below for more */
|
|
@@ -10,9 +10,9 @@ links:
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
Add `<NuxtLoadingIndicator/>` in your [`app.vue`](/docs/guide/directory-structure/app) or [`layouts/`](/docs/guide/directory-structure/layouts).
|
|
13
|
+
Add `<NuxtLoadingIndicator/>` in your [`app.vue`](/docs/guide/directory-structure/app) or [`app/layouts/`](/docs/guide/directory-structure/app/layouts).
|
|
14
14
|
|
|
15
|
-
```vue [app.vue]
|
|
15
|
+
```vue [app/app.vue]
|
|
16
16
|
<template>
|
|
17
17
|
<NuxtLoadingIndicator />
|
|
18
18
|
<NuxtLayout>
|
|
@@ -16,7 +16,7 @@ Within your pages, components, and plugins you can use useAsyncData to get acces
|
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
|
-
```vue [pages/index.vue]
|
|
19
|
+
```vue [app/pages/index.vue]
|
|
20
20
|
<script setup lang="ts">
|
|
21
21
|
const { data, status, error, refresh, clear } = await useAsyncData(
|
|
22
22
|
'mountains',
|
|
@@ -37,7 +37,7 @@ If you're using a custom useAsyncData wrapper, do not await it in the composable
|
|
|
37
37
|
|
|
38
38
|
The built-in `watch` option allows automatically rerunning the fetcher function when any changes are detected.
|
|
39
39
|
|
|
40
|
-
```vue [pages/index.vue]
|
|
40
|
+
```vue [app/pages/index.vue]
|
|
41
41
|
<script setup lang="ts">
|
|
42
42
|
const page = ref(1)
|
|
43
43
|
const { data: posts } = await useAsyncData(
|
|
@@ -57,7 +57,7 @@ const { data: posts } = await useAsyncData(
|
|
|
57
57
|
|
|
58
58
|
You can use a computed ref, plain ref or a getter function as the key, allowing for dynamic data fetching that automatically updates when the key changes:
|
|
59
59
|
|
|
60
|
-
```vue [pages/[id\\].vue]
|
|
60
|
+
```vue [app/pages/[id\\].vue]
|
|
61
61
|
<script setup lang="ts">
|
|
62
62
|
const route = useRoute()
|
|
63
63
|
const userId = computed(() => `user-${route.params.id}`)
|