@nuxt/docs 4.2.1 → 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/01.introduction.md +1 -1
- package/1.getting-started/02.installation.md +2 -5
- package/1.getting-started/03.configuration.md +27 -27
- package/1.getting-started/04.views.md +5 -5
- package/1.getting-started/05.assets.md +7 -7
- package/1.getting-started/06.styling.md +9 -5
- package/1.getting-started/07.routing.md +8 -8
- package/1.getting-started/08.seo-meta.md +7 -3
- package/1.getting-started/09.transitions.md +6 -6
- package/1.getting-started/10.data-fetching.md +2 -2
- package/1.getting-started/11.state-management.md +2 -2
- package/1.getting-started/12.error-handling.md +15 -9
- package/1.getting-started/13.server.md +2 -2
- package/1.getting-started/14.layers.md +50 -16
- package/1.getting-started/15.prerendering.md +6 -0
- package/1.getting-started/16.deployment.md +2 -1
- package/1.getting-started/17.testing.md +44 -3
- package/1.getting-started/18.upgrade.md +37 -24
- package/{2.guide/1.directory-structure → 2.directory-structure}/0.nuxt.md +1 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/0.output.md +1 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.assets.md +2 -2
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.components.md +6 -2
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.composables.md +2 -2
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.layouts.md +35 -3
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.middleware.md +1 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.pages.md +28 -7
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.plugins.md +5 -2
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.utils.md +3 -3
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.app.md +4 -4
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.error.md +10 -8
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.content.md +2 -2
- package/2.directory-structure/1.layers.md +87 -0
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.modules.md +13 -3
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.node_modules.md +2 -2
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.server.md +27 -7
- package/{2.guide/1.directory-structure → 2.directory-structure}/1.shared.md +3 -3
- package/{2.guide/1.directory-structure → 2.directory-structure}/2.env.md +2 -2
- package/{2.guide/1.directory-structure → 2.directory-structure}/2.nuxtignore.md +1 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/2.nuxtrc.md +4 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/3.nuxt-config.md +1 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/3.package.md +1 -1
- package/{2.guide/1.directory-structure → 2.directory-structure}/3.tsconfig.md +1 -0
- package/2.directory-structure/index.md +65 -0
- package/{2.guide → 3.guide}/0.index.md +10 -7
- package/{2.guide/2.concepts/3.rendering.md → 3.guide/1.concepts/1.rendering.md} +2 -27
- package/{2.guide/2.concepts/2.vuejs-development.md → 3.guide/1.concepts/10.vuejs-development.md} +4 -3
- package/{2.guide/2.concepts/10.nuxt-lifecycle.md → 3.guide/1.concepts/2.nuxt-lifecycle.md} +33 -26
- package/{2.guide/2.concepts/1.auto-imports.md → 3.guide/1.concepts/3.auto-imports.md} +5 -5
- package/{2.guide/2.concepts → 3.guide/1.concepts}/4.server-engine.md +3 -3
- package/{2.guide/2.concepts → 3.guide/1.concepts}/5.modules.md +15 -2
- package/{2.guide/2.concepts → 3.guide/1.concepts}/7.esm.md +1 -0
- package/{2.guide/2.concepts → 3.guide/1.concepts}/8.typescript.md +9 -5
- package/{2.guide/5.best-practices → 3.guide/2.best-practices}/performance.md +2 -2
- package/3.guide/3.ai/.navigation.yml +3 -0
- package/3.guide/3.ai/1.mcp.md +277 -0
- package/3.guide/3.ai/2.llms-txt.md +65 -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/{2.guide/4.recipes → 3.guide/5.recipes}/1.custom-routing.md +1 -1
- package/{2.guide/4.recipes → 3.guide/5.recipes}/2.vite-plugin.md +5 -1
- package/{2.guide/4.recipes → 3.guide/5.recipes}/3.custom-usefetch.md +2 -2
- package/{2.guide/4.recipes → 3.guide/5.recipes}/4.sessions-and-authentication.md +2 -2
- package/{2.guide/3.going-further → 3.guide/6.going-further}/1.events.md +2 -3
- package/{2.guide/3.going-further → 3.guide/6.going-further}/1.experimental-features.md +19 -4
- package/{2.guide/3.going-further → 3.guide/6.going-further}/1.internals.md +5 -4
- package/{2.guide/3.going-further → 3.guide/6.going-further}/10.runtime-config.md +3 -3
- package/{2.guide/3.going-further → 3.guide/6.going-further}/2.hooks.md +3 -3
- package/{2.guide/3.going-further → 3.guide/6.going-further}/4.kit.md +1 -1
- package/{2.guide/3.going-further → 3.guide/6.going-further}/6.nuxt-app.md +3 -3
- package/{2.guide/3.going-further → 3.guide/6.going-further}/7.layers.md +38 -12
- package/{3.api → 4.api}/1.components/1.nuxt-client-fallback.md +4 -0
- package/{3.api → 4.api}/1.components/12.nuxt-route-announcer.md +1 -3
- package/{3.api → 4.api}/1.components/13.nuxt-time.md +0 -2
- package/{3.api → 4.api}/1.components/2.nuxt-page.md +2 -2
- package/{3.api → 4.api}/1.components/3.nuxt-layout.md +6 -6
- package/{3.api → 4.api}/1.components/5.nuxt-loading-indicator.md +1 -1
- package/{3.api → 4.api}/1.components/7.nuxt-welcome.md +2 -2
- package/{3.api → 4.api}/1.components/8.nuxt-island.md +9 -2
- package/{3.api → 4.api}/2.composables/use-app-config.md +1 -1
- package/{3.api → 4.api}/2.composables/use-async-data.md +3 -3
- package/4.api/2.composables/use-cookie.md +183 -0
- package/{3.api → 4.api}/2.composables/use-error.md +2 -2
- package/{3.api → 4.api}/2.composables/use-fetch.md +33 -33
- package/{3.api → 4.api}/2.composables/use-head.md +16 -1
- package/{3.api → 4.api}/2.composables/use-lazy-fetch.md +8 -8
- package/{3.api → 4.api}/2.composables/use-nuxt-app.md +6 -4
- package/{3.api → 4.api}/2.composables/use-response-header.md +1 -1
- package/{3.api → 4.api}/2.composables/use-route-announcer.md +0 -2
- package/{3.api → 4.api}/2.composables/use-route.md +1 -1
- package/{3.api → 4.api}/2.composables/use-router.md +2 -2
- package/{3.api → 4.api}/2.composables/use-runtime-config.md +1 -1
- package/{3.api → 4.api}/2.composables/use-state.md +10 -0
- package/{3.api → 4.api}/3.utils/$fetch.md +1 -1
- package/{3.api → 4.api}/3.utils/abort-navigation.md +1 -1
- package/{3.api → 4.api}/3.utils/add-route-middleware.md +1 -1
- package/{3.api → 4.api}/3.utils/call-once.md +0 -2
- package/{3.api → 4.api}/3.utils/create-error.md +6 -6
- package/{3.api → 4.api}/3.utils/define-nuxt-plugin.md +12 -12
- package/{3.api → 4.api}/3.utils/define-nuxt-route-middleware.md +2 -2
- package/{3.api → 4.api}/3.utils/define-page-meta.md +14 -7
- package/{3.api → 4.api}/3.utils/navigate-to.md +10 -10
- package/{3.api → 4.api}/3.utils/refresh-cookie.md +0 -2
- package/{3.api → 4.api}/3.utils/set-page-layout.md +36 -0
- package/{3.api → 4.api}/3.utils/set-response-status.md +2 -2
- package/{3.api → 4.api}/3.utils/show-error.md +3 -3
- package/{3.api → 4.api}/3.utils/update-app-config.md +2 -2
- package/{3.api → 4.api}/4.commands/add.md +11 -11
- package/4.api/4.commands/analyze.md +42 -0
- package/4.api/4.commands/build-module.md +42 -0
- package/4.api/4.commands/build.md +47 -0
- package/{3.api → 4.api}/4.commands/cleanup.md +6 -6
- package/4.api/4.commands/dev.md +60 -0
- package/{3.api → 4.api}/4.commands/devtools.md +7 -7
- package/4.api/4.commands/generate.md +42 -0
- package/4.api/4.commands/info.md +33 -0
- package/4.api/4.commands/init.md +50 -0
- package/4.api/4.commands/module.md +84 -0
- package/4.api/4.commands/prepare.md +41 -0
- package/4.api/4.commands/preview.md +44 -0
- package/4.api/4.commands/test.md +40 -0
- package/4.api/4.commands/typecheck.md +44 -0
- package/4.api/4.commands/upgrade.md +37 -0
- package/{3.api → 4.api}/5.kit/1.modules.md +30 -17
- package/{3.api → 4.api}/5.kit/10.templates.md +23 -23
- package/{3.api → 4.api}/5.kit/11.nitro.md +35 -35
- package/{3.api → 4.api}/5.kit/14.builder.md +29 -17
- package/{3.api → 4.api}/5.kit/16.layers.md +12 -12
- package/{3.api → 4.api}/5.kit/2.programmatic.md +2 -2
- package/{3.api → 4.api}/5.kit/4.autoimports.md +18 -18
- package/4.api/5.kit/5.components.md +146 -0
- package/4.api/6.advanced/1.hooks.md +105 -0
- package/{3.api → 4.api}/6.nuxt-config.md +7 -6
- package/5.community/4.contribution.md +5 -5
- package/5.community/5.framework-contribution.md +1 -1
- package/5.community/6.roadmap.md +25 -25
- package/5.community/7.changelog.md +20 -0
- package/6.bridge/1.overview.md +9 -1
- package/6.bridge/2.typescript.md +1 -1
- package/6.bridge/3.bridge-composition-api.md +1 -1
- package/6.bridge/4.plugins-and-middleware.md +3 -3
- package/6.bridge/8.nitro.md +4 -0
- package/7.migration/11.server.md +1 -1
- package/7.migration/2.configuration.md +4 -4
- package/7.migration/20.module-authors.md +3 -3
- 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 +6 -6
- package/7.migration/7.component-options.md +1 -1
- package/package.json +1 -1
- package/2.guide/3.going-further/3.modules.md +0 -968
- package/3.api/2.composables/use-cookie.md +0 -183
- package/3.api/4.commands/analyze.md +0 -42
- package/3.api/4.commands/build-module.md +0 -42
- package/3.api/4.commands/build.md +0 -47
- package/3.api/4.commands/dev.md +0 -60
- package/3.api/4.commands/generate.md +0 -42
- package/3.api/4.commands/info.md +0 -33
- package/3.api/4.commands/init.md +0 -50
- package/3.api/4.commands/module.md +0 -84
- package/3.api/4.commands/prepare.md +0 -41
- package/3.api/4.commands/preview.md +0 -44
- package/3.api/4.commands/test.md +0 -40
- package/3.api/4.commands/typecheck.md +0 -44
- package/3.api/4.commands/upgrade.md +0 -37
- package/3.api/5.kit/5.components.md +0 -146
- package/3.api/6.advanced/1.hooks.md +0 -105
- /package/{2.guide/1.directory-structure → 2.directory-structure}/.navigation.yml +0 -0
- /package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/.navigation.yml +0 -0
- /package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.app-config.md +0 -0
- /package/{2.guide/1.directory-structure → 2.directory-structure}/1.public.md +0 -0
- /package/{2.guide/1.directory-structure → 2.directory-structure}/2.gitignore.md +0 -0
- /package/{2.guide → 3.guide}/.navigation.yml +0 -0
- /package/{2.guide/2.concepts → 3.guide/1.concepts}/.navigation.yml +0 -0
- /package/{2.guide/2.concepts → 3.guide/1.concepts}/9.code-style.md +0 -0
- /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/.navigation.yml +0 -0
- /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/hydration.md +0 -0
- /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/plugins.md +0 -0
- /package/{2.guide/4.recipes → 3.guide/5.recipes}/.navigation.yml +0 -0
- /package/{2.guide/3.going-further → 3.guide/6.going-further}/.navigation.yml +0 -0
- /package/{2.guide/3.going-further → 3.guide/6.going-further}/1.features.md +0 -0
- /package/{2.guide/3.going-further → 3.guide/6.going-further}/11.nightly-release-channel.md +0 -0
- /package/{2.guide/3.going-further → 3.guide/6.going-further}/9.debugging.md +0 -0
- /package/{2.guide/3.going-further → 3.guide/6.going-further}/index.md +0 -0
- /package/{3.api → 4.api}/.navigation.yml +0 -0
- /package/{3.api → 4.api}/1.components/.navigation.yml +0 -0
- /package/{3.api → 4.api}/1.components/1.client-only.md +0 -0
- /package/{3.api → 4.api}/1.components/1.dev-only.md +0 -0
- /package/{3.api → 4.api}/1.components/10.nuxt-picture.md +0 -0
- /package/{3.api → 4.api}/1.components/11.teleports.md +0 -0
- /package/{3.api → 4.api}/1.components/4.nuxt-link.md +0 -0
- /package/{3.api → 4.api}/1.components/6.nuxt-error-boundary.md +0 -0
- /package/{3.api → 4.api}/1.components/9.nuxt-img.md +0 -0
- /package/{3.api → 4.api}/2.composables/.navigation.yml +0 -0
- /package/{3.api → 4.api}/2.composables/on-prehydrate.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-head-safe.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-hydration.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-lazy-async-data.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-loading-indicator.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-nuxt-data.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-preview-mode.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-request-event.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-request-fetch.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-request-header.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-request-headers.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-request-url.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-runtime-hook.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-seo-meta.md +0 -0
- /package/{3.api → 4.api}/2.composables/use-server-seo-meta.md +0 -0
- /package/{3.api → 4.api}/3.utils/.navigation.yml +0 -0
- /package/{3.api → 4.api}/3.utils/clear-error.md +0 -0
- /package/{3.api → 4.api}/3.utils/clear-nuxt-data.md +0 -0
- /package/{3.api → 4.api}/3.utils/clear-nuxt-state.md +0 -0
- /package/{3.api → 4.api}/3.utils/define-lazy-hydration-component.md +0 -0
- /package/{3.api → 4.api}/3.utils/define-nuxt-component.md +0 -0
- /package/{3.api → 4.api}/3.utils/define-route-rules.md +0 -0
- /package/{3.api → 4.api}/3.utils/on-before-route-leave.md +0 -0
- /package/{3.api → 4.api}/3.utils/on-before-route-update.md +0 -0
- /package/{3.api → 4.api}/3.utils/on-nuxt-ready.md +0 -0
- /package/{3.api → 4.api}/3.utils/prefetch-components.md +0 -0
- /package/{3.api → 4.api}/3.utils/preload-components.md +0 -0
- /package/{3.api → 4.api}/3.utils/preload-route-components.md +0 -0
- /package/{3.api → 4.api}/3.utils/prerender-routes.md +0 -0
- /package/{3.api → 4.api}/3.utils/refresh-nuxt-data.md +0 -0
- /package/{3.api → 4.api}/3.utils/reload-nuxt-app.md +0 -0
- /package/{3.api → 4.api}/4.commands/.navigation.yml +0 -0
- /package/{3.api → 4.api}/5.kit/.navigation.yml +0 -0
- /package/{3.api → 4.api}/5.kit/10.runtime-config.md +0 -0
- /package/{3.api → 4.api}/5.kit/12.resolving.md +0 -0
- /package/{3.api → 4.api}/5.kit/13.logging.md +0 -0
- /package/{3.api → 4.api}/5.kit/15.examples.md +0 -0
- /package/{3.api → 4.api}/5.kit/3.compatibility.md +0 -0
- /package/{3.api → 4.api}/5.kit/6.context.md +0 -0
- /package/{3.api → 4.api}/5.kit/7.pages.md +0 -0
- /package/{3.api → 4.api}/5.kit/8.layout.md +0 -0
- /package/{3.api → 4.api}/5.kit/9.head.md +0 -0
- /package/{3.api → 4.api}/5.kit/9.plugins.md +0 -0
- /package/{3.api → 4.api}/6.advanced/.navigation.yml +0 -0
- /package/{3.api → 4.api}/6.advanced/2.import-meta.md +0 -0
- /package/{3.api → 4.api}/index.md +0 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Use Hooks & Extend Types"
|
|
3
|
+
description: "Master lifecycle hooks, virtual files and TypeScript declarations in your modules."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Here are some advanced patterns for authoring modules, including hooks, templates, and type augmentation.
|
|
7
|
+
|
|
8
|
+
## Use Lifecycle Hooks
|
|
9
|
+
|
|
10
|
+
[Lifecycle hooks](/docs/4.x/guide/going-further/hooks) allow you to expand almost every aspect of Nuxt. Modules can hook to them programmatically or through the `hooks` map in their definition.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
|
|
14
|
+
|
|
15
|
+
export default defineNuxtModule({
|
|
16
|
+
// Hook to the `app:error` hook through the `hooks` map
|
|
17
|
+
hooks: {
|
|
18
|
+
'app:error': (err) => {
|
|
19
|
+
console.info(`This error happened: ${err}`)
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
setup (options, nuxt) {
|
|
23
|
+
// Programmatically hook to the `pages:extend` hook
|
|
24
|
+
nuxt.hook('pages:extend', (pages) => {
|
|
25
|
+
console.info(`Discovered ${pages.length} pages`)
|
|
26
|
+
})
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
:read-more{to="/docs/4.x/api/advanced/hooks"}
|
|
32
|
+
|
|
33
|
+
::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/nuxt-lifecycle-hooks?friend=nuxt" target="_blank"}
|
|
34
|
+
Watch Vue School video about using Nuxt lifecycle hooks in modules.
|
|
35
|
+
::
|
|
36
|
+
|
|
37
|
+
::note
|
|
38
|
+
**Module cleanup**
|
|
39
|
+
:br
|
|
40
|
+
:br
|
|
41
|
+
If your module opens, handles, or starts a watcher, you should close it when the Nuxt lifecycle is done. The `close` hook is available for this.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { defineNuxtModule } from '@nuxt/kit'
|
|
45
|
+
|
|
46
|
+
export default defineNuxtModule({
|
|
47
|
+
setup (options, nuxt) {
|
|
48
|
+
nuxt.hook('close', async (nuxt) => {
|
|
49
|
+
// Your custom code here
|
|
50
|
+
})
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
::
|
|
55
|
+
|
|
56
|
+
### Create Custom Hooks
|
|
57
|
+
|
|
58
|
+
Modules can also define and call their own hooks, which is a powerful pattern for making your module extensible.
|
|
59
|
+
|
|
60
|
+
If you expect other modules to be able to subscribe to your module's hooks, you should call them in the `modules:done` hook. This ensures that all other modules have had a chance to be set up and register their listeners to your hook during their own `setup` function.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// my-module/module.ts
|
|
64
|
+
import { defineNuxtModule } from '@nuxt/kit'
|
|
65
|
+
|
|
66
|
+
export interface ModuleHooks {
|
|
67
|
+
'my-module:custom-hook': (payload: { foo: string }) => void
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default defineNuxtModule({
|
|
71
|
+
setup (options, nuxt) {
|
|
72
|
+
// Call your hook in `modules:done`
|
|
73
|
+
nuxt.hook('modules:done', async () => {
|
|
74
|
+
const payload = { foo: 'bar' }
|
|
75
|
+
await nuxt.callHook('my-module:custom-hook', payload)
|
|
76
|
+
})
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Add Virtual Files
|
|
82
|
+
|
|
83
|
+
If you need to add a virtual file that can be imported into the user's app, you can use the `addTemplate` utility.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { addTemplate, defineNuxtModule } from '@nuxt/kit'
|
|
87
|
+
|
|
88
|
+
export default defineNuxtModule({
|
|
89
|
+
setup (options, nuxt) {
|
|
90
|
+
// The file is added to Nuxt's internal virtual file system and can be imported from '#build/my-module-feature.mjs'
|
|
91
|
+
addTemplate({
|
|
92
|
+
filename: 'my-module-feature.mjs',
|
|
93
|
+
getContents: () => 'export const myModuleFeature = () => "hello world !"',
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For the server, you should use the `addServerTemplate` utility instead.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { addServerTemplate, defineNuxtModule } from '@nuxt/kit'
|
|
103
|
+
|
|
104
|
+
export default defineNuxtModule({
|
|
105
|
+
setup (options, nuxt) {
|
|
106
|
+
// The file is added to Nitro's virtual file system and can be imported in the server code from 'my-server-module.mjs'
|
|
107
|
+
addServerTemplate({
|
|
108
|
+
filename: 'my-server-module.mjs',
|
|
109
|
+
getContents: () => 'export const myServerModule = () => "hello world !"',
|
|
110
|
+
})
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Update Virtual Files
|
|
116
|
+
|
|
117
|
+
If you need to update your templates/virtual files, you can leverage the `updateTemplates` utility like this:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
nuxt.hook('builder:watch', (event, path) => {
|
|
121
|
+
if (path.includes('my-module-feature.config')) {
|
|
122
|
+
// This will reload the template that you registered
|
|
123
|
+
updateTemplates({ filter: t => t.filename === 'my-module-feature.mjs' })
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Add Type Declarations
|
|
129
|
+
|
|
130
|
+
You might also want to add a type declaration to the user's project (for example, to augment a Nuxt interface
|
|
131
|
+
or provide a global type of your own). For this, Nuxt provides the `addTypeTemplate` utility that both
|
|
132
|
+
writes a template to the disk and adds a reference to it in the generated `nuxt.d.ts` file.
|
|
133
|
+
|
|
134
|
+
If your module should augment types handled by Nuxt, you can use `addTypeTemplate` to perform this operation:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
import { addTemplate, addTypeTemplate, defineNuxtModule } from '@nuxt/kit'
|
|
138
|
+
|
|
139
|
+
export default defineNuxtModule({
|
|
140
|
+
setup (options, nuxt) {
|
|
141
|
+
addTypeTemplate({
|
|
142
|
+
filename: 'types/my-module.d.ts',
|
|
143
|
+
getContents: () => `// Generated by my-module
|
|
144
|
+
interface MyModuleNitroRules {
|
|
145
|
+
myModule?: { foo: 'bar' }
|
|
146
|
+
}
|
|
147
|
+
declare module 'nitropack/types' {
|
|
148
|
+
interface NitroRouteRules extends MyModuleNitroRules {}
|
|
149
|
+
interface NitroRouteConfig extends MyModuleNitroRules {}
|
|
150
|
+
}
|
|
151
|
+
export {}`,
|
|
152
|
+
})
|
|
153
|
+
},
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If you need more granular control, you can use the `prepare:types` hook to register a callback that will inject your types.
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
const template = addTemplate({ /* template options */ })
|
|
161
|
+
nuxt.hook('prepare:types', ({ references }) => {
|
|
162
|
+
references.push({ path: template.dst })
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Extend TypeScript Config
|
|
167
|
+
|
|
168
|
+
There are multiple ways to extend the TypeScript configuration of the user's project from your module.
|
|
169
|
+
|
|
170
|
+
The simplest way is to modify the Nuxt configuration directly like this:
|
|
171
|
+
|
|
172
|
+
<!-- @case-police-ignore tsConfig -->
|
|
173
|
+
```ts
|
|
174
|
+
// extend tsconfig.app.json
|
|
175
|
+
nuxt.options.typescript.tsConfig.include ??= []
|
|
176
|
+
nuxt.options.typescript.tsConfig.include.push(resolve('./augments.d.ts'))
|
|
177
|
+
|
|
178
|
+
// extend tsconfig.shared.json
|
|
179
|
+
nuxt.options.typescript.sharedTsConfig.include ??= []
|
|
180
|
+
nuxt.options.typescript.sharedTsConfig.include.push(resolve('./augments.d.ts'))
|
|
181
|
+
|
|
182
|
+
// extend tsconfig.node.json
|
|
183
|
+
nuxt.options.typescript.nodeTsConfig.include ??= []
|
|
184
|
+
nuxt.options.typescript.nodeTsConfig.include.push(resolve('./augments.d.ts'))
|
|
185
|
+
|
|
186
|
+
// extend tsconfig.server.json
|
|
187
|
+
nuxt.options.nitro.typescript ??= {}
|
|
188
|
+
nuxt.options.nitro.typescript.tsConfig ??= {}
|
|
189
|
+
nuxt.options.nitro.typescript.tsConfig.include ??= []
|
|
190
|
+
nuxt.options.nitro.typescript.tsConfig.include.push(resolve('./augments.d.ts'))
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Alternatively, you can use the `prepare:types` and `nitro:prepare:types` hooks to extend the TypeScript references for specific type contexts, or modify the TypeScript configuration similar to the example above.
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
nuxt.hook('prepare:types', ({ references, sharedReferences, nodeReferences }) => {
|
|
197
|
+
// extend app context
|
|
198
|
+
references.push({ path: resolve('./augments.d.ts') })
|
|
199
|
+
// extend shared context
|
|
200
|
+
sharedReferences.push({ path: resolve('./augments.d.ts') })
|
|
201
|
+
// extend node context
|
|
202
|
+
nodeReferences.push({ path: resolve('./augments.d.ts') })
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
nuxt.hook('nitro:prepare:types', ({ references }) => {
|
|
206
|
+
// extend server context
|
|
207
|
+
references.push({ path: resolve('./augments.d.ts') })
|
|
208
|
+
})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
::note
|
|
212
|
+
TypeScript references add files to the type context [without being affected by the `exclude` option in `tsconfig.json`](https://www.typescriptlang.org/tsconfig/#exclude).
|
|
213
|
+
::
|
|
214
|
+
|
|
215
|
+
## Augment Types
|
|
216
|
+
|
|
217
|
+
Nuxt automatically includes your module's directories in the appropriate type contexts. To augment types from your module, all you need to do is place the type declaration file in the appropriate directory based on the augmented type context. Alternatively, you can [extend the TypeScript configuration](#extend-typescript-config) to augment from an arbitrary location.
|
|
218
|
+
|
|
219
|
+
- `my-module/runtime/` - app type context (except for the `runtime/server` directory)
|
|
220
|
+
- `my-module/runtime/server/` - server type context
|
|
221
|
+
- `my-module/` - node type context (except for the `runtime/` and `runtime/server` directories)
|
|
222
|
+
|
|
223
|
+
```bash [Directory Structure]
|
|
224
|
+
-| my-module/ # node type context
|
|
225
|
+
---| runtime/ # app type context
|
|
226
|
+
------| augments.app.d.ts
|
|
227
|
+
------| server/ # server type context
|
|
228
|
+
---------| augments.server.d.ts
|
|
229
|
+
---| module.ts
|
|
230
|
+
---| augments.node.d.ts
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Known Limitations
|
|
234
|
+
|
|
235
|
+
#### Type-Checking Server Routes in App Context
|
|
236
|
+
|
|
237
|
+
Server routes are also type-checked using `tsconfig.app.json` in addition to `tsconfig.server.json`.
|
|
238
|
+
|
|
239
|
+
This is required because Nuxt infers the return types of your server endpoints to provide response types in [`$fetch`](/docs/4.x/api/utils/dollarfetch) and [`useFetch`](/docs/4.x/api/composables/use-fetch).
|
|
240
|
+
|
|
241
|
+
::warning
|
|
242
|
+
This can cause issues when using **server-only types** in your route files. For example, if a module creates a server-only virtual file using [`addServerTemplate`](/docs/api/kit/templates#addservertemplate) and you declare types for it in `tsconfig.server.json`, those type declarations will only be available in the server context. When the app context type-checks your server routes, it won't recognize these server-only types and will report errors. To resolve this, you unfortunately need to declare such types in the app context as well.
|
|
243
|
+
::
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Test Your Module"
|
|
3
|
+
description: "Learn how to test your Nuxt module with unit, integration and E2E tests."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Testing helps ensure your module works as expected given various setups. Find in this section how to perform various kinds of tests against your module.
|
|
7
|
+
|
|
8
|
+
## Write Unit Tests
|
|
9
|
+
|
|
10
|
+
::tip
|
|
11
|
+
We're still discussing and exploring how to ease unit and integration testing on Nuxt modules.
|
|
12
|
+
:br :br
|
|
13
|
+
[Check out this RFC to join the conversation](https://github.com/nuxt/nuxt/discussions/18399).
|
|
14
|
+
::
|
|
15
|
+
|
|
16
|
+
## Write E2E Tests
|
|
17
|
+
|
|
18
|
+
[Nuxt Test Utils](/docs/4.x/getting-started/testing) is the go-to library to help you test your module in an end-to-end way. Here's the workflow to adopt with it:
|
|
19
|
+
|
|
20
|
+
1. Create a Nuxt application to be used as a "fixture" inside `test/fixtures/*`
|
|
21
|
+
2. Setup Nuxt with this fixture inside your test file
|
|
22
|
+
3. Interact with the fixture using utilities from `@nuxt/test-utils` (e.g. fetching a page)
|
|
23
|
+
4. Perform checks related to this fixture (e.g. "HTML contains ...")
|
|
24
|
+
5. Repeat
|
|
25
|
+
|
|
26
|
+
In practice, the fixture:
|
|
27
|
+
|
|
28
|
+
```ts [test/fixtures/ssr/nuxt.config.ts]
|
|
29
|
+
// 1. Create a Nuxt application to be used as a "fixture"
|
|
30
|
+
import MyModule from '../../../src/module'
|
|
31
|
+
|
|
32
|
+
export default defineNuxtConfig({
|
|
33
|
+
ssr: true,
|
|
34
|
+
modules: [
|
|
35
|
+
MyModule,
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
And its test:
|
|
41
|
+
|
|
42
|
+
```ts [test/rendering.ts]
|
|
43
|
+
import { describe, expect, it } from 'vitest'
|
|
44
|
+
import { fileURLToPath } from 'node:url'
|
|
45
|
+
import { $fetch, setup } from '@nuxt/test-utils/e2e'
|
|
46
|
+
|
|
47
|
+
describe('ssr', async () => {
|
|
48
|
+
// 2. Setup Nuxt with this fixture inside your test file
|
|
49
|
+
await setup({
|
|
50
|
+
rootDir: fileURLToPath(new URL('./fixtures/ssr', import.meta.url)),
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('renders the index page', async () => {
|
|
54
|
+
// 3. Interact with the fixture using utilities from `@nuxt/test-utils`
|
|
55
|
+
const html = await $fetch('/')
|
|
56
|
+
|
|
57
|
+
// 4. Perform checks related to this fixture
|
|
58
|
+
expect(html).toContain('<div>ssr</div>')
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// 5. Repeat
|
|
63
|
+
describe('csr', async () => { /* ... */ })
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
::tip
|
|
67
|
+
An example of such a workflow is available on [the module starter](https://github.com/nuxt/starter/blob/module/test/basic.test.ts).
|
|
68
|
+
::
|
|
69
|
+
|
|
70
|
+
## Test Manually
|
|
71
|
+
|
|
72
|
+
Having a playground Nuxt application to test your module when developing it is really useful. [The module starter integrates one for that purpose](/docs/4.x/guide/modules/getting-started#develop-your-module).
|
|
73
|
+
|
|
74
|
+
You can test your module with other Nuxt applications (applications that are not part of your module repository) locally. To do so, you can use [`npm pack`](https://docs.npmjs.com/cli/commands/npm-pack/) command, or your package manager equivalent, to create a tarball from your module. Then in your test project, you can add your module to `package.json` packages as: `"my-module": "file:/path/to/tarball.tgz"`.
|
|
75
|
+
|
|
76
|
+
After that, you should be able to reference `my-module` like in any regular project.
|
|
@@ -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
|
+
::
|
|
@@ -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 [app/pages directory](/docs/4.x/
|
|
8
|
+
In Nuxt, your routing is defined by the structure of your files inside the [app/pages directory](/docs/4.x/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
|
|
|
@@ -26,9 +26,13 @@ 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
|
-
Next, we need to import and add it to our [`nuxt.config.ts`](/docs/4.x/
|
|
35
|
+
Next, we need to import and add it to our [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file:
|
|
32
36
|
|
|
33
37
|
```ts [nuxt.config.ts]
|
|
34
38
|
import yaml from '@rollup/plugin-yaml'
|
|
@@ -12,7 +12,7 @@ However, Nuxt provides a way to create a custom fetcher for your API (or multipl
|
|
|
12
12
|
|
|
13
13
|
## Custom `$fetch`
|
|
14
14
|
|
|
15
|
-
Let's create a custom `$fetch` instance with a [Nuxt plugin](/docs/4.x/
|
|
15
|
+
Let's create a custom `$fetch` instance with a [Nuxt plugin](/docs/4.x/directory-structure/app/plugins).
|
|
16
16
|
|
|
17
17
|
::note
|
|
18
18
|
`$fetch` is a configured instance of [ofetch](https://github.com/unjs/ofetch) which supports adding the base URL of your Nuxt server as well as direct function calls during SSR (avoiding HTTP roundtrips).
|
|
@@ -98,7 +98,7 @@ import type { UseFetchOptions } from 'nuxt/app'
|
|
|
98
98
|
|
|
99
99
|
interface CustomError {
|
|
100
100
|
message: string
|
|
101
|
-
|
|
101
|
+
status: number
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export function useAPI<T> (
|
|
@@ -65,7 +65,7 @@ export default defineEventHandler(async (event) => {
|
|
|
65
65
|
return {}
|
|
66
66
|
}
|
|
67
67
|
throw createError({
|
|
68
|
-
|
|
68
|
+
status: 401,
|
|
69
69
|
message: 'Bad credentials',
|
|
70
70
|
})
|
|
71
71
|
})
|
|
@@ -155,7 +155,7 @@ export default defineEventHandler(async (event) => {
|
|
|
155
155
|
|
|
156
156
|
## Protect App Routes
|
|
157
157
|
|
|
158
|
-
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/4.x/
|
|
158
|
+
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/4.x/directory-structure/app/middleware) to protect the route on the client side and redirect users to the login page.
|
|
159
159
|
|
|
160
160
|
`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.
|
|
161
161
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Events"
|
|
2
|
+
title: "Creating Custom Events"
|
|
3
3
|
description: "Nuxt provides a powerful event system powered by hookable."
|
|
4
|
+
navigation.title: "Custom Events"
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Events
|
|
7
|
-
|
|
8
7
|
Using events is a great way to decouple your application and allow for more flexible and modular communication between different parts of your code. Events can have multiple listeners that do not depend on each other. For example, you may wish to send an email to your user each time an order has shipped. Instead of coupling your order processing code to your email code, you can emit an event which a listener can receive and use to dispatch an email.
|
|
9
8
|
|
|
10
9
|
The Nuxt event system is powered by [unjs/hookable](https://github.com/unjs/hookable), which is the same library that powers the Nuxt hooks system.
|
|
@@ -131,7 +131,7 @@ Emits `app:chunkError` hook when there is an error loading vite/webpack chunks.
|
|
|
131
131
|
|
|
132
132
|
By default, Nuxt will also perform a reload of the new route when a chunk fails to load when navigating to a new route (`automatic`).
|
|
133
133
|
|
|
134
|
-
Setting `automatic-immediate` will lead Nuxt to perform a reload of the current route right when a chunk fails to load (instead of waiting for navigation). This is useful for chunk errors that are not triggered by navigation, e.g., when your Nuxt app fails to load a [lazy component](/docs/4.x/
|
|
134
|
+
Setting `automatic-immediate` will lead Nuxt to perform a reload of the current route right when a chunk fails to load (instead of waiting for navigation). This is useful for chunk errors that are not triggered by navigation, e.g., when your Nuxt app fails to load a [lazy component](/docs/4.x/directory-structure/app/components#dynamic-imports). A potential downside of this behavior is undesired reloads, e.g., when your app does not need the chunk that caused the error.
|
|
135
135
|
|
|
136
136
|
You can disable automatic handling by setting this to `false`, or handle chunk errors manually by setting it to `manual`.
|
|
137
137
|
|
|
@@ -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.
|
|
@@ -318,7 +333,7 @@ export default defineNuxtConfig({
|
|
|
318
333
|
})
|
|
319
334
|
```
|
|
320
335
|
|
|
321
|
-
:read-more{to="/docs/4.x/
|
|
336
|
+
:read-more{to="/docs/4.x/directory-structure/app/components#server-components"}
|
|
322
337
|
|
|
323
338
|
::read-more{icon="i-simple-icons-github" to="https://github.com/nuxt/nuxt/issues/19772" target="_blank"}
|
|
324
339
|
You can follow the server components roadmap on GitHub.
|
|
@@ -541,7 +556,7 @@ export default defineNuxtConfig({
|
|
|
541
556
|
})
|
|
542
557
|
```
|
|
543
558
|
|
|
544
|
-
This allows modules to access additional metadata from the page metadata in the build context. If you are using this within a module, it's recommended also to [augment the `NuxtPage` types with your keys](/docs/4.x/
|
|
559
|
+
This allows modules to access additional metadata from the page metadata in the build context. If you are using this within a module, it's recommended also to [augment the `NuxtPage` types with your keys](/docs/4.x/directory-structure/app/pages#typing-custom-metadata).
|
|
545
560
|
|
|
546
561
|
## navigationRepaint
|
|
547
562
|
|
|
@@ -665,7 +680,7 @@ export default defineNuxtConfig({
|
|
|
665
680
|
})
|
|
666
681
|
```
|
|
667
682
|
|
|
668
|
-
::read-more{icon="i-simple-icons-github" color="gray" to="/docs/4.x/
|
|
683
|
+
::read-more{icon="i-simple-icons-github" color="gray" to="/docs/4.x/directory-structure/app/components#delayed-or-lazy-hydration"}
|
|
669
684
|
Read more about lazy hydration.
|
|
670
685
|
::
|
|
671
686
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "How Nuxt Works?"
|
|
3
3
|
description: "Nuxt is a minimal but highly customizable framework to build web applications."
|
|
4
|
+
navigation: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
This guide helps you better understand Nuxt internals to develop new solutions and module integrations on top of Nuxt.
|
|
@@ -15,7 +16,7 @@ allowing different components to communicate with each other. You can think of i
|
|
|
15
16
|
This context is globally available to be used with [Nuxt Kit](/docs/4.x/guide/going-further/kit) composables.
|
|
16
17
|
Therefore only one instance of Nuxt is allowed to run per process.
|
|
17
18
|
|
|
18
|
-
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).
|
|
19
20
|
|
|
20
21
|
For more details, check out [the source code](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nuxt.ts).
|
|
21
22
|
|
|
@@ -30,7 +31,7 @@ Global usage is possible for the browser but not on the server, to avoid sharing
|
|
|
30
31
|
|
|
31
32
|
Since [`useNuxtApp`](/docs/4.x/api/composables/use-nuxt-app) throws an exception if context is currently unavailable, if your composable does not always require `nuxtApp`, you can use [`tryUseNuxtApp`](/docs/4.x/api/composables/use-nuxt-app#tryusenuxtapp) instead, which will return `null` instead of throwing an exception.
|
|
32
33
|
|
|
33
|
-
To extend the `nuxtApp` interface and hook into different stages or access contexts, we can use [Nuxt Plugins](/docs/4.x/
|
|
34
|
+
To extend the `nuxtApp` interface and hook into different stages or access contexts, we can use [Nuxt Plugins](/docs/4.x/directory-structure/app/plugins).
|
|
34
35
|
|
|
35
36
|
Check [Nuxt App](/docs/4.x/api/composables/use-nuxt-app) for more information about this interface.
|
|
36
37
|
|
|
@@ -76,6 +77,6 @@ Nuxt builds and bundles project using Node.js but also has a runtime side.
|
|
|
76
77
|
|
|
77
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!
|
|
78
79
|
|
|
79
|
-
`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.
|
|
80
81
|
|
|
81
|
-
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).
|