@nuxt/docs 4.2.2 → 4.3.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/02.installation.md +2 -5
- package/1.getting-started/03.configuration.md +5 -5
- package/1.getting-started/06.styling.md +5 -1
- package/1.getting-started/07.routing.md +1 -1
- package/1.getting-started/08.seo-meta.md +4 -0
- package/1.getting-started/12.error-handling.md +12 -6
- package/1.getting-started/14.layers.md +47 -13
- package/1.getting-started/15.prerendering.md +6 -0
- package/1.getting-started/16.deployment.md +1 -0
- package/1.getting-started/17.testing.md +12 -2
- package/1.getting-started/18.upgrade.md +14 -1
- package/2.directory-structure/1.app/1.components.md +4 -0
- package/2.directory-structure/1.app/1.layouts.md +32 -0
- package/2.directory-structure/1.app/1.pages.md +21 -0
- package/2.directory-structure/1.app/1.plugins.md +3 -0
- package/2.directory-structure/1.app/3.error.md +9 -5
- package/2.directory-structure/1.layers.md +87 -0
- package/2.directory-structure/1.modules.md +12 -2
- package/2.directory-structure/1.node_modules.md +1 -1
- package/2.directory-structure/1.server.md +24 -4
- package/2.directory-structure/2.nuxtrc.md +3 -0
- package/2.directory-structure/3.tsconfig.md +1 -0
- package/2.directory-structure/index.md +4 -0
- package/3.guide/0.index.md +8 -2
- package/3.guide/1.concepts/1.rendering.md +1 -0
- package/3.guide/1.concepts/2.nuxt-lifecycle.md +1 -1
- package/3.guide/1.concepts/5.modules.md +14 -1
- package/3.guide/1.concepts/8.typescript.md +6 -2
- package/3.guide/3.ai/1.mcp.md +22 -0
- package/3.guide/4.modules/.navigation.yml +3 -0
- package/3.guide/4.modules/1.getting-started.md +103 -0
- package/3.guide/4.modules/2.module-anatomy.md +138 -0
- package/3.guide/4.modules/3.recipes-basics.md +330 -0
- package/3.guide/4.modules/4.recipes-advanced.md +243 -0
- package/3.guide/4.modules/5.testing.md +76 -0
- package/3.guide/4.modules/6.best-practices.md +104 -0
- package/3.guide/4.modules/7.ecosystem.md +32 -0
- package/3.guide/4.modules/index.md +36 -0
- package/3.guide/{4.recipes → 5.recipes}/2.vite-plugin.md +4 -0
- package/3.guide/{4.recipes → 5.recipes}/3.custom-usefetch.md +1 -1
- package/3.guide/{4.recipes → 5.recipes}/4.sessions-and-authentication.md +1 -1
- package/3.guide/{5.going-further → 6.going-further}/1.experimental-features.md +15 -0
- package/3.guide/{5.going-further → 6.going-further}/1.internals.md +3 -3
- package/3.guide/{5.going-further → 6.going-further}/10.runtime-config.md +1 -1
- package/3.guide/{5.going-further → 6.going-further}/2.hooks.md +1 -1
- package/3.guide/{5.going-further → 6.going-further}/4.kit.md +1 -1
- package/3.guide/{5.going-further → 6.going-further}/7.layers.md +26 -0
- package/4.api/1.components/1.nuxt-client-fallback.md +4 -0
- package/4.api/1.components/3.nuxt-layout.md +2 -2
- package/4.api/1.components/8.nuxt-island.md +9 -2
- package/4.api/2.composables/use-async-data.md +3 -3
- package/4.api/2.composables/use-error.md +2 -2
- package/4.api/2.composables/use-fetch.md +2 -2
- package/4.api/2.composables/use-head.md +16 -1
- package/4.api/2.composables/use-nuxt-app.md +2 -0
- package/4.api/2.composables/use-state.md +10 -0
- package/4.api/3.utils/create-error.md +6 -6
- package/4.api/3.utils/define-nuxt-route-middleware.md +1 -1
- package/4.api/3.utils/define-page-meta.md +8 -1
- package/4.api/3.utils/set-page-layout.md +36 -0
- package/4.api/3.utils/set-response-status.md +2 -2
- package/4.api/3.utils/show-error.md +3 -3
- package/4.api/4.commands/add.md +1 -1
- package/4.api/5.kit/1.modules.md +15 -2
- package/4.api/5.kit/14.builder.md +14 -2
- package/4.api/6.nuxt-config.md +2 -2
- package/5.community/4.contribution.md +5 -5
- package/5.community/5.framework-contribution.md +1 -1
- package/5.community/6.roadmap.md +1 -1
- package/5.community/7.changelog.md +10 -0
- package/6.bridge/1.overview.md +8 -0
- package/6.bridge/4.plugins-and-middleware.md +1 -1
- package/6.bridge/8.nitro.md +4 -0
- package/7.migration/2.configuration.md +2 -2
- package/7.migration/20.module-authors.md +2 -2
- package/7.migration/7.component-options.md +1 -1
- package/package.json +1 -1
- package/3.guide/5.going-further/3.modules.md +0 -968
- /package/3.guide/{4.recipes → 5.recipes}/.navigation.yml +0 -0
- /package/3.guide/{4.recipes → 5.recipes}/1.custom-routing.md +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/.navigation.yml +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/1.events.md +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/1.features.md +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/11.nightly-release-channel.md +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/6.nuxt-app.md +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/9.debugging.md +0 -0
- /package/3.guide/{5.going-further → 6.going-further}/index.md +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Follow Best Practices"
|
|
3
|
+
description: "Build performant and maintainable Nuxt modules with these guidelines."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
With great power comes great responsibility. While modules are powerful, here are some best practices to keep in mind while authoring modules to keep applications performant and developer experience great.
|
|
7
|
+
|
|
8
|
+
## Handle Async Setup
|
|
9
|
+
|
|
10
|
+
As we've seen, Nuxt modules can be asynchronous. For example, you may want to develop a module that needs fetching some API or calling an async function.
|
|
11
|
+
|
|
12
|
+
However, be careful with asynchronous behaviors as Nuxt will wait for your module to setup before going to the next module and starting the development server, build process, etc. Prefer deferring time-consuming logic to Nuxt hooks.
|
|
13
|
+
|
|
14
|
+
::warning
|
|
15
|
+
If your module takes more than **1 second** to setup, Nuxt will emit a warning about it.
|
|
16
|
+
::
|
|
17
|
+
|
|
18
|
+
## Prefix Your Exports
|
|
19
|
+
|
|
20
|
+
Nuxt modules should provide an explicit prefix for any exposed configuration, plugin, API, composable, component, or server route to avoid conflicts with other modules, Nuxt internals, or user-defined code.
|
|
21
|
+
|
|
22
|
+
Ideally, prefix them with your module's name. For example, if your module is called `nuxt-foo`:
|
|
23
|
+
|
|
24
|
+
| Type | ❌ Avoid | ✅ Prefer |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| Components | `<Button>`, `<Modal>` | `<FooButton>`, `<FooModal>` |
|
|
27
|
+
| Composables | `useData()`, `useModal()` | `useFooData()`, `useFooModal()` |
|
|
28
|
+
| Server routes | `/api/track`, `/api/data` | `/api/_foo/track`, `/api/_foo/data` |
|
|
29
|
+
|
|
30
|
+
### Server Routes
|
|
31
|
+
|
|
32
|
+
This is particularly important for server routes, where common paths like `/api/auth`, `/api/login`, or `/api/user` are very likely already used by the application.
|
|
33
|
+
|
|
34
|
+
Use a unique prefix based on your module name:
|
|
35
|
+
- `/api/_foo/...` (using underscore prefix)
|
|
36
|
+
- `/_foo/...` (for non-API routes)
|
|
37
|
+
|
|
38
|
+
## Use Lifecycle Hooks
|
|
39
|
+
|
|
40
|
+
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.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { addServerHandler, defineNuxtModule } from 'nuxt/kit'
|
|
44
|
+
import semver from 'semver'
|
|
45
|
+
|
|
46
|
+
export default defineNuxtModule({
|
|
47
|
+
meta: {
|
|
48
|
+
name: 'my-database-module',
|
|
49
|
+
version: '1.0.0',
|
|
50
|
+
},
|
|
51
|
+
async onInstall (nuxt) {
|
|
52
|
+
// One-time setup: create database schema, generate config files, etc.
|
|
53
|
+
await generateDatabaseConfig(nuxt.options.rootDir)
|
|
54
|
+
},
|
|
55
|
+
async onUpgrade (nuxt, options, previousVersion) {
|
|
56
|
+
// Handle version-specific migrations
|
|
57
|
+
if (semver.lt(previousVersion, '1.0.0')) {
|
|
58
|
+
await migrateLegacyData()
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
setup (options, nuxt) {
|
|
62
|
+
// Regular setup logic that runs on every build
|
|
63
|
+
addServerHandler({ /* ... */ })
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This pattern prevents unnecessary work on every build and provides a better developer experience. See the [lifecycle hooks documentation](/docs/4.x/api/kit/modules#using-lifecycle-hooks-for-module-installation-and-upgrade) for more details.
|
|
69
|
+
|
|
70
|
+
## Be TypeScript Friendly
|
|
71
|
+
|
|
72
|
+
Nuxt has first-class TypeScript integration for the best developer experience.
|
|
73
|
+
|
|
74
|
+
Exposing types and using TypeScript to develop modules benefits users even when not using TypeScript directly.
|
|
75
|
+
|
|
76
|
+
## Use ESM Syntax
|
|
77
|
+
|
|
78
|
+
Nuxt relies on native ESM. Please read [Native ES Modules](/docs/4.x/guide/concepts/esm) for more information.
|
|
79
|
+
|
|
80
|
+
## Document Your Module
|
|
81
|
+
|
|
82
|
+
Consider documenting module usage in the readme file:
|
|
83
|
+
|
|
84
|
+
- Why use this module?
|
|
85
|
+
- How to use this module?
|
|
86
|
+
- What does this module do?
|
|
87
|
+
|
|
88
|
+
Linking to the integration website and documentation is always a good idea.
|
|
89
|
+
|
|
90
|
+
## Provide a Demo
|
|
91
|
+
|
|
92
|
+
It's a good practice to make a minimal reproduction with your module and [StackBlitz](https://nuxt.new/s/v4) that you add to your module readme.
|
|
93
|
+
|
|
94
|
+
This not only provides potential users of your module a quick and easy way to experiment with the module but also an easy way for them to build minimal reproductions they can send you when they encounter issues.
|
|
95
|
+
|
|
96
|
+
## Stay Version Agnostic
|
|
97
|
+
|
|
98
|
+
Nuxt, Nuxt Kit, and other new toolings are made to have both forward and backward compatibility in mind.
|
|
99
|
+
|
|
100
|
+
Please use "X for Nuxt" instead of "X for Nuxt 3" to avoid fragmentation in the ecosystem and prefer using `meta.compatibility` to set Nuxt version constraints.
|
|
101
|
+
|
|
102
|
+
## Follow Starter Conventions
|
|
103
|
+
|
|
104
|
+
The module starter comes with a default set of tools and configurations (e.g. ESLint configuration). If you plan on open-sourcing your module, sticking with those defaults ensures your module shares a consistent coding style with other [community modules](/modules) out there, making it easier for others to contribute.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Publish & Share Your Module"
|
|
3
|
+
description: "Join the Nuxt module ecosystem and publish your module to npm."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The [Nuxt module ecosystem](/modules) represents more than 35 million monthly NPM downloads and provides extended functionalities and integrations with all sort of tools. You can be part of this ecosystem!
|
|
7
|
+
|
|
8
|
+
::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/exploring-nuxt-modules-ecosystem-and-module-types?friend=nuxt" target="_blank"}
|
|
9
|
+
Watch Vue School video about Nuxt module types.
|
|
10
|
+
::
|
|
11
|
+
|
|
12
|
+
## Understand Module Types
|
|
13
|
+
|
|
14
|
+
**Official modules** are modules prefixed (scoped) with `@nuxt/` (e.g. [`@nuxt/content`](https://content.nuxt.com)). They are made and maintained actively by the Nuxt team. Like with the framework, contributions from the community are more than welcome to help make them better!
|
|
15
|
+
|
|
16
|
+
**Community modules** are modules prefixed (scoped) with `@nuxtjs/` (e.g. [`@nuxtjs/tailwindcss`](https://tailwindcss.nuxtjs.org)). They are proven modules made and maintained by community members. Again, contributions are welcome from anyone.
|
|
17
|
+
|
|
18
|
+
**Third-party and other community modules** are modules (often) prefixed with `nuxt-`. Anyone can make them, using this prefix allows these modules to be discoverable on npm. This is the best starting point to draft and try an idea!
|
|
19
|
+
|
|
20
|
+
**Private or personal modules** are modules made for your own use case or company. They don't need to follow any naming rules to work with Nuxt and are often seen scoped under an npm organization (e.g. `@my-company/nuxt-auth`)
|
|
21
|
+
|
|
22
|
+
## List Your Module
|
|
23
|
+
|
|
24
|
+
Any community modules are welcome to be listed on [the module list](/modules). To be listed, [open an issue in the nuxt/modules](https://github.com/nuxt/modules/issues/new?template=module_request.yml) repository. The Nuxt team can help you to apply best practices before listing.
|
|
25
|
+
|
|
26
|
+
## Join nuxt-modules
|
|
27
|
+
|
|
28
|
+
By moving your modules to [nuxt-modules](https://github.com/nuxt-modules), there is always someone else to help, and this way, we can join forces to make one perfect solution.
|
|
29
|
+
|
|
30
|
+
If you have an already published and working module, and want to transfer it to `nuxt-modules`, [open an issue in nuxt/modules](https://github.com/nuxt/modules/issues/new).
|
|
31
|
+
|
|
32
|
+
By joining `nuxt-modules` we can rename your community module under the `@nuxtjs/` scope and provide a subdomain (e.g. `my-module.nuxtjs.org`) for its documentation.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Module Author Guide'
|
|
3
|
+
titleTemplate: '%s'
|
|
4
|
+
description: 'Learn how to create a Nuxt module to integrate, enhance or extend any Nuxt applications.'
|
|
5
|
+
navigation: false
|
|
6
|
+
surround: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Nuxt's [configuration](/docs/4.x/api/nuxt-config) and [hooks](/docs/4.x/guide/going-further/hooks) systems make it possible to customize every aspect of Nuxt and add any integration you might need (Vue plugins, CMS, server routes, components, logging, etc.).
|
|
10
|
+
|
|
11
|
+
**Nuxt modules** are functions that sequentially run when starting Nuxt in development mode using `nuxt dev` or building a project for production with `nuxt build`.
|
|
12
|
+
With modules, you can encapsulate, properly test, and share custom solutions as npm packages without adding unnecessary boilerplate to your project, or requiring changes to Nuxt itself.
|
|
13
|
+
|
|
14
|
+
::card-group{class="sm:grid-cols-1"}
|
|
15
|
+
::card{icon="i-lucide-rocket" title="Create Your First Module" to="/docs/4.x/guide/modules/getting-started"}
|
|
16
|
+
Learn how to create your first Nuxt module using the official starter template.
|
|
17
|
+
::
|
|
18
|
+
::card{icon="i-lucide-box" title="Understand Module Structure" to="/docs/4.x/guide/modules/module-anatomy"}
|
|
19
|
+
Learn how Nuxt modules are structured and how to define them.
|
|
20
|
+
::
|
|
21
|
+
::card{icon="i-lucide-code" title="Add Plugins, Components & More" to="/docs/4.x/guide/modules/recipes-basics"}
|
|
22
|
+
Learn how to inject plugins, components, composables and server routes from your module.
|
|
23
|
+
::
|
|
24
|
+
::card{icon="i-lucide-layers" title="Use Hooks & Extend Types" to="/docs/4.x/guide/modules/recipes-advanced"}
|
|
25
|
+
Master lifecycle hooks, virtual files and TypeScript declarations in your modules.
|
|
26
|
+
::
|
|
27
|
+
::card{icon="i-lucide-test-tube" title="Test Your Module" to="/docs/4.x/guide/modules/testing"}
|
|
28
|
+
Learn how to test your Nuxt module with unit, integration and E2E tests.
|
|
29
|
+
::
|
|
30
|
+
::card{icon="i-lucide-medal" title="Follow Best Practices" to="/docs/4.x/guide/modules/best-practices"}
|
|
31
|
+
Build performant and maintainable Nuxt modules with these guidelines.
|
|
32
|
+
::
|
|
33
|
+
::card{icon="i-lucide-globe" title="Publish & Share Your Module" to="/docs/4.x/guide/modules/ecosystem"}
|
|
34
|
+
Join the Nuxt module ecosystem and publish your module to npm.
|
|
35
|
+
::
|
|
36
|
+
::
|
|
@@ -26,6 +26,10 @@ First, we need to install the Vite plugin, for our example, we'll use `@rollup/p
|
|
|
26
26
|
bun add @rollup/plugin-yaml
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
```bash [deno]
|
|
30
|
+
deno add npm:@rollup/plugin-yaml
|
|
31
|
+
```
|
|
32
|
+
|
|
29
33
|
::
|
|
30
34
|
|
|
31
35
|
Next, we need to import and add it to our [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file:
|
|
@@ -248,6 +248,21 @@ export default defineNuxtConfig({
|
|
|
248
248
|
})
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
+
Payload extraction also works for routes using ISR (Incremental Static Regeneration) or SWR (Stale-While-Revalidate) caching strategies. This allows CDNs to cache payload files alongside HTML, improving client-side navigation performance for cached routes.
|
|
252
|
+
|
|
253
|
+
```ts twoslash [nuxt.config.ts]
|
|
254
|
+
export default defineNuxtConfig({
|
|
255
|
+
experimental: {
|
|
256
|
+
payloadExtraction: true,
|
|
257
|
+
},
|
|
258
|
+
routeRules: {
|
|
259
|
+
// Payload files will be generated for these cached routes
|
|
260
|
+
'/products/**': { isr: 3600 },
|
|
261
|
+
'/blog/**': { swr: true },
|
|
262
|
+
},
|
|
263
|
+
})
|
|
264
|
+
```
|
|
265
|
+
|
|
251
266
|
## clientFallback
|
|
252
267
|
|
|
253
268
|
Enables the experimental [`<NuxtClientFallback>`](/docs/4.x/api/components/nuxt-client-fallback) component for rendering content on the client if there's an error in SSR.
|
|
@@ -16,7 +16,7 @@ allowing different components to communicate with each other. You can think of i
|
|
|
16
16
|
This context is globally available to be used with [Nuxt Kit](/docs/4.x/guide/going-further/kit) composables.
|
|
17
17
|
Therefore only one instance of Nuxt is allowed to run per process.
|
|
18
18
|
|
|
19
|
-
To extend the Nuxt interface and hook into different stages of the build process, we can use [Nuxt
|
|
19
|
+
To extend the Nuxt interface and hook into different stages of the build process, we can use [Nuxt modules](/docs/4.x/guide/modules).
|
|
20
20
|
|
|
21
21
|
For more details, check out [the source code](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nuxt.ts).
|
|
22
22
|
|
|
@@ -77,6 +77,6 @@ Nuxt builds and bundles project using Node.js but also has a runtime side.
|
|
|
77
77
|
|
|
78
78
|
While both areas can be extended, that runtime context is isolated from build-time. Therefore, they are not supposed to share state, code, or context other than runtime configuration!
|
|
79
79
|
|
|
80
|
-
`nuxt.config` and [Nuxt
|
|
80
|
+
`nuxt.config` and [Nuxt modules](/docs/4.x/guide/modules) can be used to extend the build context, and [Nuxt Plugins](/docs/4.x/directory-structure/app/plugins) can be used to extend runtime.
|
|
81
81
|
|
|
82
|
-
When building an application for production, `nuxt build` will generate a standalone build in the `.output` directory, independent of `nuxt.config` and [Nuxt modules](/docs/4.x/guide/
|
|
82
|
+
When building an application for production, `nuxt build` will generate a standalone build in the `.output` directory, independent of `nuxt.config` and [Nuxt modules](/docs/4.x/guide/modules).
|
|
@@ -41,7 +41,7 @@ Instead of passing non-serializable objects or functions into your application f
|
|
|
41
41
|
|
|
42
42
|
### Environment Variables
|
|
43
43
|
|
|
44
|
-
The most common way to provide configuration is by using
|
|
44
|
+
The most common way to provide configuration is by using environment variables.
|
|
45
45
|
|
|
46
46
|
::note
|
|
47
47
|
The Nuxt CLI has built-in support for reading your `.env` file in development, build and generate. But when you run your built server, **your `.env` file will not be read**.
|
|
@@ -9,7 +9,7 @@ The hooking system is powered by [unjs/hookable](https://github.com/unjs/hookabl
|
|
|
9
9
|
|
|
10
10
|
## Nuxt Hooks (Build Time)
|
|
11
11
|
|
|
12
|
-
These hooks are available for [Nuxt
|
|
12
|
+
These hooks are available for [Nuxt modules](/docs/4.x/guide/modules) and build context.
|
|
13
13
|
|
|
14
14
|
### Within `nuxt.config.ts`
|
|
15
15
|
|
|
@@ -3,7 +3,7 @@ title: "Nuxt Kit"
|
|
|
3
3
|
description: "@nuxt/kit provides features for module authors."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Nuxt Kit provides composable utilities to make interacting with [Nuxt Hooks](/docs/4.x/api/advanced/hooks), the [Nuxt Interface](/docs/4.x/guide/going-further/internals#the-nuxt-interface) and developing [Nuxt
|
|
6
|
+
Nuxt Kit provides composable utilities to make interacting with [Nuxt Hooks](/docs/4.x/api/advanced/hooks), the [Nuxt Interface](/docs/4.x/guide/going-further/internals#the-nuxt-interface) and developing [Nuxt modules](/docs/4.x/guide/modules) super easy.
|
|
7
7
|
|
|
8
8
|
::read-more{to="/docs/4.x/api/kit"}
|
|
9
9
|
Discover all Nuxt Kit utilities.
|
|
@@ -249,6 +249,32 @@ export default defineNuxtConfig({
|
|
|
249
249
|
})
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
+
## Disabling Modules from Layers
|
|
253
|
+
|
|
254
|
+
When extending a layer, you might want to disable certain modules that it includes. You can do this by setting the module's config key to `false` in your Nuxt config.
|
|
255
|
+
|
|
256
|
+
```ts [nuxt.config.ts]
|
|
257
|
+
export default defineNuxtConfig({
|
|
258
|
+
extends: ['./base-layer'],
|
|
259
|
+
// Disable modules from the layer by setting their config key to false
|
|
260
|
+
image: false, // Disables @nuxt/image
|
|
261
|
+
pinia: false, // Disables @pinia/nuxt
|
|
262
|
+
})
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
::note
|
|
266
|
+
The config key is defined by each module. Common examples include `image` for `@nuxt/image`, `pinia` for `@pinia/nuxt`, and `content` for `@nuxt/content`. Check the module's documentation for its specific config key.
|
|
267
|
+
::
|
|
268
|
+
|
|
269
|
+
This is useful when:
|
|
270
|
+
- A layer includes modules you don't need in your project
|
|
271
|
+
- You want to use a different implementation than what the layer provides
|
|
272
|
+
- You need to disable analytics or other modules in specific environments
|
|
273
|
+
|
|
274
|
+
::tip
|
|
275
|
+
You can also use this approach to disable modules in your own project - not just those from layers. Setting a module's config key to `false` will prevent its setup function from running while still generating types for the module.
|
|
276
|
+
::
|
|
277
|
+
|
|
252
278
|
## Multi-Layer Support for Nuxt Modules
|
|
253
279
|
|
|
254
280
|
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.
|
|
@@ -54,6 +54,10 @@ This component is experimental and in order to use it you must enable the `exper
|
|
|
54
54
|
- **type**: `boolean`
|
|
55
55
|
- **default**: `false`
|
|
56
56
|
|
|
57
|
+
::warning{icon="i-ph-warning-duotone"}
|
|
58
|
+
The `placeholder` and `fallback` props render content as raw HTML. Do not pass untrusted user input to these props as it may lead to XSS vulnerabilities. Use the `#fallback` or `#placeholder` slots instead for dynamic content that needs proper escaping.
|
|
59
|
+
::
|
|
60
|
+
|
|
57
61
|
```vue
|
|
58
62
|
<template>
|
|
59
63
|
<!-- render <span>Hello world</span> server-side if the default slot fails to render -->
|
|
@@ -22,8 +22,8 @@ You can use `<NuxtLayout />` component to activate the `default` layout on `app.
|
|
|
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 [`app/layouts/`](/docs/4.x/directory-structure/app/layouts) directory.
|
|
26
|
-
- **type**: `string`
|
|
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/4.x/directory-structure/app/layouts) directory, or `false` to disable the layout.
|
|
26
|
+
- **type**: `string | false`
|
|
27
27
|
- **default**: `default`
|
|
28
28
|
|
|
29
29
|
```vue [app/pages/index.vue]
|
|
@@ -32,13 +32,20 @@ Server only components use `<NuxtIsland>` under the hood
|
|
|
32
32
|
- **type**: `Record<string, any>`
|
|
33
33
|
- `source`: Remote source to call the island to render.
|
|
34
34
|
- **type**: `string`
|
|
35
|
-
- **dangerouslyLoadClientComponents**: Required to load components from a remote source.
|
|
35
|
+
- **dangerouslyLoadClientComponents**: Required to load client components from a remote source.
|
|
36
36
|
- **type**: `boolean`
|
|
37
37
|
- **default**: `false`
|
|
38
38
|
|
|
39
39
|
::note
|
|
40
40
|
Remote islands need `experimental.componentIslands` to be `'local+remote'` in your `nuxt.config`.
|
|
41
|
-
|
|
41
|
+
::
|
|
42
|
+
|
|
43
|
+
::warning{icon="i-ph-warning-duotone"}
|
|
44
|
+
Using the `source` prop to render content from a remote server is inherently dangerous. When you specify a remote `source`, you are fully trusting that server to provide safe HTML content that will be rendered directly in your application.
|
|
45
|
+
|
|
46
|
+
This is similar to using `v-html` with external content - the remote server can inject any HTML, including potentially malicious content. **Only use `source` with servers you fully trust and control.**
|
|
47
|
+
|
|
48
|
+
The `dangerouslyLoadClientComponents` prop controls an additional layer of risk: whether to also download and execute client components from the remote source. Even with `dangerouslyLoadClientComponents` disabled (the default), you are still trusting the remote server's HTML output.
|
|
42
49
|
::
|
|
43
50
|
|
|
44
51
|
::note
|
|
@@ -25,8 +25,8 @@ const { data, status, pending, error, refresh, clear } = await useAsyncData(
|
|
|
25
25
|
</script>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
::warning
|
|
29
|
-
If you're using a custom useAsyncData wrapper, do not await it in the composable
|
|
28
|
+
::warning{to="/docs/4.x/guide/recipes/custom-usefetch#custom-usefetchuseasyncdata"}
|
|
29
|
+
If you're using a custom `useAsyncData` wrapper, do not await it in the composable as that can cause unexpected behavior. See recipe for custom async data fetcher.
|
|
30
30
|
::
|
|
31
31
|
|
|
32
32
|
::note
|
|
@@ -148,7 +148,7 @@ The `handler` function should be **side-effect free** to ensure predictable beha
|
|
|
148
148
|
- `immediate`: when set to `false`, will prevent the request from firing immediately. (defaults to `true`)
|
|
149
149
|
- `default`: a factory function to set the default value of the `data`, before the async function resolves - useful with the `lazy: true` or `immediate: false` option
|
|
150
150
|
- `transform`: a function that can be used to alter `handler` function result after resolving
|
|
151
|
-
- `getCachedData`: Provide a function which returns cached data.
|
|
151
|
+
- `getCachedData`: Provide a function which returns cached data. An `undefined` return value will trigger a fetch. By default, this is:
|
|
152
152
|
```ts
|
|
153
153
|
const getDefaultCachedData = (key, nuxtApp, ctx) => nuxtApp.isHydrating
|
|
154
154
|
? nuxtApp.payload.data[key]
|
|
@@ -22,8 +22,8 @@ You can use this composable in your components, pages, or plugins to access or r
|
|
|
22
22
|
|
|
23
23
|
```ts
|
|
24
24
|
interface NuxtError<DataT = unknown> {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
status: number
|
|
26
|
+
statusText: string
|
|
27
27
|
message: string
|
|
28
28
|
data?: DataT
|
|
29
29
|
error?: true
|
|
@@ -25,8 +25,8 @@ const { data, status, error, refresh, clear } = await useFetch('/api/modules', {
|
|
|
25
25
|
</script>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
::warning
|
|
29
|
-
If you're using a custom useFetch wrapper, do not await it in the composable
|
|
28
|
+
::warning{to="/docs/4.x/guide/recipes/custom-usefetch#custom-usefetchuseasyncdata"}
|
|
29
|
+
If you're using a custom `useFetch` wrapper, do not await it in the composable as that can cause unexpected behavior. See recipe for custom async data fetcher.
|
|
30
30
|
::
|
|
31
31
|
|
|
32
32
|
::note
|
|
@@ -38,7 +38,7 @@ The properties of `useHead` can be dynamic, accepting `ref`, `computed` and `rea
|
|
|
38
38
|
## Type
|
|
39
39
|
|
|
40
40
|
```ts [Signature]
|
|
41
|
-
export function useHead (meta: MaybeComputedRef<MetaObject>):
|
|
41
|
+
export function useHead (meta: MaybeComputedRef<MetaObject>): ActiveHeadEntry<UseHeadInput>
|
|
42
42
|
|
|
43
43
|
interface MetaObject {
|
|
44
44
|
title?: string
|
|
@@ -52,6 +52,21 @@ interface MetaObject {
|
|
|
52
52
|
htmlAttrs?: HtmlAttributes
|
|
53
53
|
bodyAttrs?: BodyAttributes
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
interface ActiveHeadEntry<Input> {
|
|
57
|
+
/**
|
|
58
|
+
* Updates the entry with new input.
|
|
59
|
+
*
|
|
60
|
+
* Will first clear any side effects for previous input.
|
|
61
|
+
*/
|
|
62
|
+
patch: (input: Input) => void
|
|
63
|
+
/**
|
|
64
|
+
* Dispose the entry, removing it from the active head.
|
|
65
|
+
*
|
|
66
|
+
* Will queue side effects for removal.
|
|
67
|
+
*/
|
|
68
|
+
dispose: () => void
|
|
69
|
+
}
|
|
55
70
|
```
|
|
56
71
|
|
|
57
72
|
See [@unhead/schema](https://github.com/unjs/unhead/blob/main/packages/vue/src/types/schema.ts) for more detailed types.
|
|
@@ -136,6 +136,8 @@ Nuxt exposes the following properties through `ssrContext`:
|
|
|
136
136
|
|
|
137
137
|
It is also possible to use more advanced types, such as `ref`, `reactive`, `shallowRef`, `shallowReactive` and `NuxtError`.
|
|
138
138
|
|
|
139
|
+
#### Custom Reducer/Reviver
|
|
140
|
+
|
|
139
141
|
Since [Nuxt v3.4](https://nuxt.com/blog/v3-4#payload-enhancements), it is possible to define your own reducer/reviver for types that are not supported by Nuxt.
|
|
140
142
|
|
|
141
143
|
:video-accordion{title="Watch a video from Alexander Lichter about serializing payloads, especially with regards to classes" videoId="8w6ffRBs8a4"}
|
|
@@ -46,3 +46,13 @@ export function useState<T> (key: string, init?: () => T | Ref<T>): Ref<T>
|
|
|
46
46
|
- `key`: A unique key ensuring that data fetching is properly de-duplicated across requests. If you do not provide a key, then a key that is unique to the file and line number of the instance of [`useState`](/docs/4.x/api/composables/use-state) will be generated for you.
|
|
47
47
|
- `init`: A function that provides initial value for the state when not initiated. This function can also return a `Ref`.
|
|
48
48
|
- `T`: (typescript only) Specify the type of state
|
|
49
|
+
|
|
50
|
+
## Troubleshooting
|
|
51
|
+
|
|
52
|
+
### `Cannot stringify arbitrary non-POJOs`
|
|
53
|
+
|
|
54
|
+
This error occurs when you try to store a non-serializable payload with `useState`, such as class instances.
|
|
55
|
+
|
|
56
|
+
If you want to store class instances with `useState` that are not supported by Nuxt, you can use [`definePayloadPlugin`](/docs/4.x/api/composables/use-nuxt-app#custom-reducerreviver) to add a custom serializer and deserializer for your classes.
|
|
57
|
+
|
|
58
|
+
:read-more{to="/docs/4.x/api/composables/use-nuxt-app#payload"}
|
|
@@ -12,9 +12,9 @@ You can use this function to create an error object with additional metadata. It
|
|
|
12
12
|
|
|
13
13
|
## Parameters
|
|
14
14
|
|
|
15
|
-
- `err`: `string | { cause, data, message, name, stack,
|
|
15
|
+
- `err`: `string | { cause, data, message, name, stack, status, statusText, fatal }`
|
|
16
16
|
|
|
17
|
-
You can pass either a string or an object to the `createError` function. If you pass a string, it will be used as the error `message`, and the `
|
|
17
|
+
You can pass either a string or an object to the `createError` function. If you pass a string, it will be used as the error `message`, and the `status` will default to `500`. If you pass an object, you can set multiple properties of the error, such as `status`, `message`, and other error properties.
|
|
18
18
|
|
|
19
19
|
## In Vue App
|
|
20
20
|
|
|
@@ -30,7 +30,7 @@ If you throw an error created with `createError`:
|
|
|
30
30
|
const route = useRoute()
|
|
31
31
|
const { data } = await useFetch(`/api/movies/${route.params.slug}`)
|
|
32
32
|
if (!data.value) {
|
|
33
|
-
throw createError({
|
|
33
|
+
throw createError({ status: 404, statusText: 'Page Not Found' })
|
|
34
34
|
}
|
|
35
35
|
</script>
|
|
36
36
|
```
|
|
@@ -44,12 +44,12 @@ Use `createError` to trigger error handling in server API routes.
|
|
|
44
44
|
```ts [server/api/error.ts]
|
|
45
45
|
export default eventHandler(() => {
|
|
46
46
|
throw createError({
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
status: 404,
|
|
48
|
+
statusText: 'Page Not Found',
|
|
49
49
|
})
|
|
50
50
|
})
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
In API routes, using `createError` by passing an object with a short `
|
|
53
|
+
In API routes, using `createError` by passing an object with a short `statusText` is recommended because it can be accessed on the client side. Otherwise, a `message` passed to `createError` on an API route will not propagate to the client. Alternatively, you can use the `data` property to pass data back to the client. In any case, always consider avoiding to put dynamic user input to the message to avoid potential security issues.
|
|
54
54
|
|
|
55
55
|
:read-more{to="/docs/4.x/getting-started/error-handling"}
|
|
@@ -39,7 +39,7 @@ You can use route middleware to throw errors and show helpful error messages:
|
|
|
39
39
|
```ts [app/middleware/error.ts]
|
|
40
40
|
export default defineNuxtRouteMiddleware((to) => {
|
|
41
41
|
if (to.params.id === '1') {
|
|
42
|
-
throw createError({
|
|
42
|
+
throw createError({ status: 404, statusText: 'Page Not Found' })
|
|
43
43
|
}
|
|
44
44
|
})
|
|
45
45
|
```
|
|
@@ -32,6 +32,7 @@ interface PageMeta {
|
|
|
32
32
|
path?: string
|
|
33
33
|
props?: RouteRecordRaw['props']
|
|
34
34
|
alias?: string | string[]
|
|
35
|
+
groups?: string[]
|
|
35
36
|
pageTransition?: boolean | TransitionProps
|
|
36
37
|
layoutTransition?: boolean | TransitionProps
|
|
37
38
|
viewTransition?: boolean | 'always'
|
|
@@ -76,6 +77,12 @@ interface PageMeta {
|
|
|
76
77
|
|
|
77
78
|
Aliases for the record. Allows defining extra paths that will behave like a copy of the record. Allows having paths shorthands like `/users/:id` and `/u/:id`. All `alias` and `path` values must share the same params.
|
|
78
79
|
|
|
80
|
+
**`groups`**
|
|
81
|
+
|
|
82
|
+
- **Type**: `string[]`
|
|
83
|
+
|
|
84
|
+
Route groups the page belongs to, based on the folder structure. Automatically populated for pages within [route groups](/docs/4.x/guide/directory-structure/app/pages#route-groups).
|
|
85
|
+
|
|
79
86
|
**`keepalive`**
|
|
80
87
|
|
|
81
88
|
- **Type**: `boolean` | [`KeepAliveProps`](https://vuejs.org/api/built-in-components#keepalive)
|
|
@@ -130,7 +137,7 @@ interface PageMeta {
|
|
|
130
137
|
|
|
131
138
|
- **Type**: `(route: RouteLocationNormalized) => boolean | Promise<boolean> | Partial<NuxtError> | Promise<Partial<NuxtError>>`
|
|
132
139
|
|
|
133
|
-
Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with `
|
|
140
|
+
Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with `status`/`statusText` to respond immediately with an error (other matches will not be checked).
|
|
134
141
|
|
|
135
142
|
**`scrollToTop`**
|
|
136
143
|
|
|
@@ -19,6 +19,42 @@ export default defineNuxtRouteMiddleware((to) => {
|
|
|
19
19
|
})
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## Passing Props to Layouts
|
|
23
|
+
|
|
24
|
+
You can pass props to the layout by providing an object as the second argument:
|
|
25
|
+
|
|
26
|
+
```ts [app/middleware/admin-layout.ts]
|
|
27
|
+
export default defineNuxtRouteMiddleware((to) => {
|
|
28
|
+
setPageLayout('admin', {
|
|
29
|
+
sidebar: true,
|
|
30
|
+
title: 'Dashboard',
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The layout can then receive these props:
|
|
36
|
+
|
|
37
|
+
```vue [app/layouts/admin.vue]
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
const props = defineProps<{
|
|
40
|
+
sidebar?: boolean
|
|
41
|
+
title?: string
|
|
42
|
+
}>()
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<div>
|
|
47
|
+
<aside v-if="sidebar">
|
|
48
|
+
Sidebar
|
|
49
|
+
</aside>
|
|
50
|
+
<main>
|
|
51
|
+
<h1>{{ title }}</h1>
|
|
52
|
+
<slot />
|
|
53
|
+
</main>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
```
|
|
57
|
+
|
|
22
58
|
::note
|
|
23
59
|
If you choose to set the layout dynamically on the server side, you _must_ do so before the layout is rendered by Vue (that is, within a plugin or route middleware) to avoid a hydration mismatch.
|
|
24
60
|
::
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'setResponseStatus'
|
|
3
|
-
description: setResponseStatus sets the
|
|
3
|
+
description: setResponseStatus sets the status (and optionally the statusText) of the response.
|
|
4
4
|
links:
|
|
5
5
|
- label: Source
|
|
6
6
|
icon: i-simple-icons-github
|
|
@@ -10,7 +10,7 @@ links:
|
|
|
10
10
|
|
|
11
11
|
Nuxt provides composables and utilities for first-class server-side-rendering support.
|
|
12
12
|
|
|
13
|
-
`setResponseStatus` sets the
|
|
13
|
+
`setResponseStatus` sets the status (and optionally the statusText) of the response.
|
|
14
14
|
|
|
15
15
|
::important
|
|
16
16
|
`setResponseStatus` can only be called in the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context).
|
|
@@ -12,13 +12,13 @@ Within the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-contex
|
|
|
12
12
|
|
|
13
13
|
**Parameters:**
|
|
14
14
|
|
|
15
|
-
- `error`: `string | Error | Partial<{ cause, data, message, name, stack,
|
|
15
|
+
- `error`: `string | Error | Partial<{ cause, data, message, name, stack, status, statusText }>`
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
18
|
showError('😱 Oh no, an error has been thrown.')
|
|
19
19
|
showError({
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
status: 404,
|
|
21
|
+
statusText: 'Page Not Found',
|
|
22
22
|
})
|
|
23
23
|
```
|
|
24
24
|
|
package/4.api/4.commands/add.md
CHANGED