@nuxt/docs-nightly 4.3.0-29356103.2f7957ac → 4.3.0-29430616.754c35a4

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.
Files changed (250) hide show
  1. package/1.getting-started/01.introduction.md +1 -1
  2. package/1.getting-started/02.installation.md +4 -6
  3. package/1.getting-started/03.configuration.md +27 -27
  4. package/1.getting-started/04.views.md +5 -5
  5. package/1.getting-started/05.assets.md +8 -8
  6. package/1.getting-started/06.styling.md +15 -15
  7. package/1.getting-started/07.routing.md +10 -6
  8. package/1.getting-started/08.seo-meta.md +3 -3
  9. package/1.getting-started/09.transitions.md +10 -10
  10. package/1.getting-started/10.data-fetching.md +16 -16
  11. package/1.getting-started/11.state-management.md +3 -3
  12. package/1.getting-started/12.error-handling.md +6 -6
  13. package/1.getting-started/13.server.md +6 -6
  14. package/1.getting-started/14.layers.md +32 -13
  15. package/1.getting-started/16.deployment.md +1 -1
  16. package/1.getting-started/17.testing.md +36 -5
  17. package/1.getting-started/18.upgrade.md +43 -35
  18. package/{2.guide/1.directory-structure → 2.directory-structure}/0.nuxt.md +1 -1
  19. package/{2.guide/1.directory-structure → 2.directory-structure}/0.output.md +1 -1
  20. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.assets.md +2 -2
  21. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.components.md +6 -6
  22. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.composables.md +2 -2
  23. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.layouts.md +3 -3
  24. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.middleware.md +5 -5
  25. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.pages.md +17 -17
  26. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.plugins.md +3 -7
  27. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/1.utils.md +3 -3
  28. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.app.md +4 -4
  29. package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.error.md +1 -3
  30. package/{2.guide/1.directory-structure → 2.directory-structure}/1.content.md +2 -2
  31. package/{2.guide/1.directory-structure → 2.directory-structure}/1.modules.md +2 -2
  32. package/{2.guide/1.directory-structure → 2.directory-structure}/1.node_modules.md +2 -2
  33. package/{2.guide/1.directory-structure → 2.directory-structure}/1.public.md +1 -1
  34. package/{2.guide/1.directory-structure → 2.directory-structure}/1.server.md +7 -7
  35. package/{2.guide/1.directory-structure → 2.directory-structure}/1.shared.md +3 -3
  36. package/{2.guide/1.directory-structure → 2.directory-structure}/2.env.md +2 -2
  37. package/{2.guide/1.directory-structure → 2.directory-structure}/2.nuxtignore.md +1 -1
  38. package/{2.guide/1.directory-structure → 2.directory-structure}/2.nuxtrc.md +1 -1
  39. package/{2.guide/1.directory-structure → 2.directory-structure}/3.nuxt-config.md +1 -1
  40. package/{2.guide/1.directory-structure → 2.directory-structure}/3.package.md +1 -1
  41. package/2.directory-structure/3.tsconfig.md +69 -0
  42. package/2.directory-structure/index.md +61 -0
  43. package/{2.guide → 3.guide}/0.index.md +10 -7
  44. package/{2.guide/2.concepts/3.rendering.md → 3.guide/1.concepts/1.rendering.md} +4 -30
  45. package/{2.guide/2.concepts/2.vuejs-development.md → 3.guide/1.concepts/10.vuejs-development.md} +7 -6
  46. package/{2.guide/2.concepts/10.nuxt-lifecycle.md → 3.guide/1.concepts/2.nuxt-lifecycle.md} +32 -25
  47. package/{2.guide/2.concepts/1.auto-imports.md → 3.guide/1.concepts/3.auto-imports.md} +7 -7
  48. package/{2.guide/2.concepts → 3.guide/1.concepts}/4.server-engine.md +3 -3
  49. package/{2.guide/2.concepts → 3.guide/1.concepts}/5.modules.md +2 -2
  50. package/{2.guide/2.concepts → 3.guide/1.concepts}/7.esm.md +3 -2
  51. package/{2.guide/2.concepts → 3.guide/1.concepts}/8.typescript.md +15 -38
  52. package/{2.guide/2.concepts → 3.guide/1.concepts}/9.code-style.md +1 -1
  53. package/{2.guide/5.best-practices → 3.guide/2.best-practices}/hydration.md +1 -1
  54. package/{2.guide/5.best-practices → 3.guide/2.best-practices}/performance.md +2 -2
  55. package/3.guide/3.ai/.navigation.yml +3 -0
  56. package/3.guide/3.ai/1.mcp.md +255 -0
  57. package/3.guide/3.ai/2.llms-txt.md +65 -0
  58. package/3.guide/4.modules/.navigation.yml +3 -0
  59. package/3.guide/4.modules/1.getting-started.md +103 -0
  60. package/3.guide/4.modules/2.module-anatomy.md +138 -0
  61. package/3.guide/4.modules/3.recipes-basics.md +299 -0
  62. package/3.guide/4.modules/4.recipes-advanced.md +231 -0
  63. package/3.guide/4.modules/5.testing.md +76 -0
  64. package/3.guide/4.modules/6.best-practices.md +104 -0
  65. package/3.guide/4.modules/7.ecosystem.md +32 -0
  66. package/3.guide/4.modules/index.md +36 -0
  67. package/{2.guide/4.recipes → 3.guide/5.recipes}/1.custom-routing.md +5 -5
  68. package/{2.guide/4.recipes → 3.guide/5.recipes}/2.vite-plugin.md +1 -1
  69. package/{2.guide/4.recipes → 3.guide/5.recipes}/3.custom-usefetch.md +1 -1
  70. package/{2.guide/4.recipes → 3.guide/5.recipes}/4.sessions-and-authentication.md +1 -1
  71. package/{2.guide/3.going-further → 3.guide/6.going-further}/1.events.md +2 -3
  72. package/{2.guide/3.going-further → 3.guide/6.going-further}/1.experimental-features.md +10 -10
  73. package/{2.guide/3.going-further → 3.guide/6.going-further}/1.features.md +1 -1
  74. package/{2.guide/3.going-further → 3.guide/6.going-further}/1.internals.md +5 -4
  75. package/{2.guide/3.going-further → 3.guide/6.going-further}/10.runtime-config.md +2 -2
  76. package/{2.guide/3.going-further → 3.guide/6.going-further}/2.hooks.md +3 -3
  77. package/{2.guide/3.going-further → 3.guide/6.going-further}/4.kit.md +1 -1
  78. package/{2.guide/3.going-further → 3.guide/6.going-further}/6.nuxt-app.md +5 -5
  79. package/{2.guide/3.going-further → 3.guide/6.going-further}/7.layers.md +42 -25
  80. package/{2.guide/3.going-further → 3.guide/6.going-further}/9.debugging.md +1 -1
  81. package/{3.api → 4.api}/1.components/10.nuxt-picture.md +1 -1
  82. package/{3.api → 4.api}/1.components/11.teleports.md +1 -1
  83. package/{3.api → 4.api}/1.components/12.nuxt-route-announcer.md +1 -3
  84. package/{3.api → 4.api}/1.components/13.nuxt-time.md +0 -2
  85. package/{3.api → 4.api}/1.components/2.nuxt-page.md +3 -3
  86. package/{3.api → 4.api}/1.components/3.nuxt-layout.md +5 -5
  87. package/{3.api → 4.api}/1.components/4.nuxt-link.md +11 -11
  88. package/{3.api → 4.api}/1.components/5.nuxt-loading-indicator.md +1 -1
  89. package/{3.api → 4.api}/1.components/6.nuxt-error-boundary.md +1 -1
  90. package/{3.api → 4.api}/1.components/7.nuxt-welcome.md +2 -2
  91. package/{3.api → 4.api}/2.composables/use-app-config.md +1 -1
  92. package/{3.api → 4.api}/2.composables/use-async-data.md +76 -13
  93. package/4.api/2.composables/use-cookie.md +183 -0
  94. package/{3.api → 4.api}/2.composables/use-fetch.md +33 -33
  95. package/{3.api → 4.api}/2.composables/use-head-safe.md +37 -20
  96. package/4.api/2.composables/use-head.md +184 -0
  97. package/{3.api → 4.api}/2.composables/use-hydration.md +24 -18
  98. package/4.api/2.composables/use-lazy-async-data.md +96 -0
  99. package/4.api/2.composables/use-lazy-fetch.md +111 -0
  100. package/{3.api → 4.api}/2.composables/use-nuxt-app.md +7 -7
  101. package/{3.api → 4.api}/2.composables/use-nuxt-data.md +1 -1
  102. package/{3.api → 4.api}/2.composables/use-request-fetch.md +1 -1
  103. package/{3.api → 4.api}/2.composables/use-response-header.md +1 -1
  104. package/{3.api → 4.api}/2.composables/use-route-announcer.md +0 -2
  105. package/{3.api → 4.api}/2.composables/use-route.md +2 -2
  106. package/4.api/2.composables/use-router.md +94 -0
  107. package/{3.api → 4.api}/2.composables/use-runtime-config.md +1 -1
  108. package/{3.api → 4.api}/2.composables/use-runtime-hook.md +1 -1
  109. package/{3.api → 4.api}/2.composables/use-state.md +1 -1
  110. package/{3.api → 4.api}/3.utils/$fetch.md +1 -1
  111. package/{3.api → 4.api}/3.utils/abort-navigation.md +3 -3
  112. package/{3.api → 4.api}/3.utils/add-route-middleware.md +1 -1
  113. package/{3.api → 4.api}/3.utils/call-once.md +0 -2
  114. package/{3.api → 4.api}/3.utils/define-lazy-hydration-component.md +4 -4
  115. package/{3.api → 4.api}/3.utils/define-nuxt-component.md +1 -1
  116. package/4.api/3.utils/define-nuxt-plugin.md +102 -0
  117. package/{3.api → 4.api}/3.utils/define-nuxt-route-middleware.md +2 -2
  118. package/{3.api → 4.api}/3.utils/define-page-meta.md +14 -14
  119. package/{3.api → 4.api}/3.utils/navigate-to.md +15 -15
  120. package/{3.api → 4.api}/3.utils/on-before-route-leave.md +1 -1
  121. package/{3.api → 4.api}/3.utils/on-before-route-update.md +1 -1
  122. package/{3.api → 4.api}/3.utils/refresh-cookie.md +1 -3
  123. package/{3.api → 4.api}/3.utils/update-app-config.md +2 -2
  124. package/{3.api → 4.api}/4.commands/add.md +11 -11
  125. package/4.api/4.commands/analyze.md +42 -0
  126. package/4.api/4.commands/build-module.md +42 -0
  127. package/4.api/4.commands/build.md +47 -0
  128. package/{3.api → 4.api}/4.commands/cleanup.md +6 -6
  129. package/4.api/4.commands/dev.md +60 -0
  130. package/{3.api → 4.api}/4.commands/devtools.md +7 -7
  131. package/4.api/4.commands/generate.md +42 -0
  132. package/4.api/4.commands/info.md +33 -0
  133. package/4.api/4.commands/init.md +50 -0
  134. package/4.api/4.commands/module.md +84 -0
  135. package/4.api/4.commands/prepare.md +41 -0
  136. package/4.api/4.commands/preview.md +44 -0
  137. package/4.api/4.commands/test.md +40 -0
  138. package/4.api/4.commands/typecheck.md +44 -0
  139. package/4.api/4.commands/upgrade.md +37 -0
  140. package/{3.api → 4.api}/5.kit/1.modules.md +18 -18
  141. package/{3.api → 4.api}/5.kit/10.templates.md +23 -23
  142. package/{3.api → 4.api}/5.kit/11.nitro.md +35 -35
  143. package/{3.api → 4.api}/5.kit/14.builder.md +21 -21
  144. package/{3.api → 4.api}/5.kit/16.layers.md +12 -12
  145. package/{3.api → 4.api}/5.kit/2.programmatic.md +2 -2
  146. package/{3.api → 4.api}/5.kit/4.autoimports.md +18 -18
  147. package/4.api/5.kit/5.components.md +146 -0
  148. package/4.api/6.advanced/1.hooks.md +105 -0
  149. package/{3.api → 4.api}/6.nuxt-config.md +29 -28
  150. package/5.community/3.reporting-bugs.md +1 -1
  151. package/5.community/4.contribution.md +4 -4
  152. package/5.community/5.framework-contribution.md +8 -8
  153. package/5.community/6.roadmap.md +25 -25
  154. package/5.community/7.changelog.md +10 -0
  155. package/6.bridge/1.overview.md +1 -1
  156. package/6.bridge/2.typescript.md +1 -1
  157. package/6.bridge/3.bridge-composition-api.md +1 -1
  158. package/6.bridge/4.plugins-and-middleware.md +2 -2
  159. package/7.migration/11.server.md +1 -1
  160. package/7.migration/2.configuration.md +5 -5
  161. package/7.migration/20.module-authors.md +3 -3
  162. package/7.migration/3.auto-imports.md +1 -1
  163. package/7.migration/5.plugins-and-middleware.md +2 -2
  164. package/7.migration/6.pages-and-layouts.md +6 -6
  165. package/README.md +1 -1
  166. package/package.json +1 -1
  167. package/2.guide/1.directory-structure/3.tsconfig.md +0 -38
  168. package/2.guide/3.going-further/3.modules.md +0 -901
  169. package/3.api/2.composables/use-cookie.md +0 -183
  170. package/3.api/2.composables/use-head.md +0 -69
  171. package/3.api/2.composables/use-lazy-async-data.md +0 -47
  172. package/3.api/2.composables/use-lazy-fetch.md +0 -55
  173. package/3.api/2.composables/use-router.md +0 -94
  174. package/3.api/3.utils/define-nuxt-plugin.md +0 -102
  175. package/3.api/4.commands/analyze.md +0 -42
  176. package/3.api/4.commands/build-module.md +0 -42
  177. package/3.api/4.commands/build.md +0 -47
  178. package/3.api/4.commands/dev.md +0 -60
  179. package/3.api/4.commands/generate.md +0 -42
  180. package/3.api/4.commands/info.md +0 -33
  181. package/3.api/4.commands/init.md +0 -50
  182. package/3.api/4.commands/module.md +0 -84
  183. package/3.api/4.commands/prepare.md +0 -41
  184. package/3.api/4.commands/preview.md +0 -44
  185. package/3.api/4.commands/test.md +0 -40
  186. package/3.api/4.commands/typecheck.md +0 -44
  187. package/3.api/4.commands/upgrade.md +0 -37
  188. package/3.api/5.kit/5.components.md +0 -146
  189. package/3.api/6.advanced/1.hooks.md +0 -105
  190. /package/{2.guide/1.directory-structure → 2.directory-structure}/.navigation.yml +0 -0
  191. /package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/.navigation.yml +0 -0
  192. /package/{2.guide/1.directory-structure → 2.directory-structure}/1.app/3.app-config.md +0 -0
  193. /package/{2.guide/1.directory-structure → 2.directory-structure}/2.gitignore.md +0 -0
  194. /package/{2.guide → 3.guide}/.navigation.yml +0 -0
  195. /package/{2.guide/2.concepts → 3.guide/1.concepts}/.navigation.yml +0 -0
  196. /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/.navigation.yml +0 -0
  197. /package/{2.guide/5.best-practices → 3.guide/2.best-practices}/plugins.md +0 -0
  198. /package/{2.guide/4.recipes → 3.guide/5.recipes}/.navigation.yml +0 -0
  199. /package/{2.guide/3.going-further → 3.guide/6.going-further}/.navigation.yml +0 -0
  200. /package/{2.guide/3.going-further → 3.guide/6.going-further}/11.nightly-release-channel.md +0 -0
  201. /package/{2.guide/3.going-further → 3.guide/6.going-further}/index.md +0 -0
  202. /package/{3.api → 4.api}/.navigation.yml +0 -0
  203. /package/{3.api → 4.api}/1.components/.navigation.yml +0 -0
  204. /package/{3.api → 4.api}/1.components/1.client-only.md +0 -0
  205. /package/{3.api → 4.api}/1.components/1.dev-only.md +0 -0
  206. /package/{3.api → 4.api}/1.components/1.nuxt-client-fallback.md +0 -0
  207. /package/{3.api → 4.api}/1.components/8.nuxt-island.md +0 -0
  208. /package/{3.api → 4.api}/1.components/9.nuxt-img.md +0 -0
  209. /package/{3.api → 4.api}/2.composables/.navigation.yml +0 -0
  210. /package/{3.api → 4.api}/2.composables/on-prehydrate.md +0 -0
  211. /package/{3.api → 4.api}/2.composables/use-error.md +0 -0
  212. /package/{3.api → 4.api}/2.composables/use-loading-indicator.md +0 -0
  213. /package/{3.api → 4.api}/2.composables/use-preview-mode.md +0 -0
  214. /package/{3.api → 4.api}/2.composables/use-request-event.md +0 -0
  215. /package/{3.api → 4.api}/2.composables/use-request-header.md +0 -0
  216. /package/{3.api → 4.api}/2.composables/use-request-headers.md +0 -0
  217. /package/{3.api → 4.api}/2.composables/use-request-url.md +0 -0
  218. /package/{3.api → 4.api}/2.composables/use-seo-meta.md +0 -0
  219. /package/{3.api → 4.api}/2.composables/use-server-seo-meta.md +0 -0
  220. /package/{3.api → 4.api}/3.utils/.navigation.yml +0 -0
  221. /package/{3.api → 4.api}/3.utils/clear-error.md +0 -0
  222. /package/{3.api → 4.api}/3.utils/clear-nuxt-data.md +0 -0
  223. /package/{3.api → 4.api}/3.utils/clear-nuxt-state.md +0 -0
  224. /package/{3.api → 4.api}/3.utils/create-error.md +0 -0
  225. /package/{3.api → 4.api}/3.utils/define-route-rules.md +0 -0
  226. /package/{3.api → 4.api}/3.utils/on-nuxt-ready.md +0 -0
  227. /package/{3.api → 4.api}/3.utils/prefetch-components.md +0 -0
  228. /package/{3.api → 4.api}/3.utils/preload-components.md +0 -0
  229. /package/{3.api → 4.api}/3.utils/preload-route-components.md +0 -0
  230. /package/{3.api → 4.api}/3.utils/prerender-routes.md +0 -0
  231. /package/{3.api → 4.api}/3.utils/refresh-nuxt-data.md +0 -0
  232. /package/{3.api → 4.api}/3.utils/reload-nuxt-app.md +0 -0
  233. /package/{3.api → 4.api}/3.utils/set-page-layout.md +0 -0
  234. /package/{3.api → 4.api}/3.utils/set-response-status.md +0 -0
  235. /package/{3.api → 4.api}/3.utils/show-error.md +0 -0
  236. /package/{3.api → 4.api}/4.commands/.navigation.yml +0 -0
  237. /package/{3.api → 4.api}/5.kit/.navigation.yml +0 -0
  238. /package/{3.api → 4.api}/5.kit/10.runtime-config.md +0 -0
  239. /package/{3.api → 4.api}/5.kit/12.resolving.md +0 -0
  240. /package/{3.api → 4.api}/5.kit/13.logging.md +0 -0
  241. /package/{3.api → 4.api}/5.kit/15.examples.md +0 -0
  242. /package/{3.api → 4.api}/5.kit/3.compatibility.md +0 -0
  243. /package/{3.api → 4.api}/5.kit/6.context.md +0 -0
  244. /package/{3.api → 4.api}/5.kit/7.pages.md +0 -0
  245. /package/{3.api → 4.api}/5.kit/8.layout.md +0 -0
  246. /package/{3.api → 4.api}/5.kit/9.head.md +0 -0
  247. /package/{3.api → 4.api}/5.kit/9.plugins.md +0 -0
  248. /package/{3.api → 4.api}/6.advanced/.navigation.yml +0 -0
  249. /package/{3.api → 4.api}/6.advanced/2.import-meta.md +0 -0
  250. /package/{3.api → 4.api}/index.md +0 -0
@@ -0,0 +1,299 @@
1
+ ---
2
+ title: "Add Plugins, Components & More"
3
+ description: "Learn how to inject plugins, components, composables and server routes from your module."
4
+ ---
5
+
6
+ Here are some common patterns used by module authors.
7
+
8
+ ## Modify Nuxt Configuration
9
+
10
+ Nuxt configuration can be read and altered by modules. Here's an example of a module enabling an experimental feature.
11
+
12
+ ```js
13
+ import { defineNuxtModule } from '@nuxt/kit'
14
+
15
+ export default defineNuxtModule({
16
+ setup (options, nuxt) {
17
+ // We create the `experimental` object if it doesn't exist yet
18
+ nuxt.options.experimental ||= {}
19
+ nuxt.options.experimental.componentIslands = true
20
+ },
21
+ })
22
+ ```
23
+
24
+ When you need to handle more complex configuration alterations, you should consider using [defu](https://github.com/unjs/defu).
25
+
26
+ ::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/extending-and-altering-nuxt-configuration-and-options?friend=nuxt" target="_blank"}
27
+ Watch Vue School video about altering Nuxt configuration.
28
+ ::
29
+
30
+ ## Expose Options to Runtime
31
+
32
+ Because modules aren't part of the application runtime, their options aren't either. However, in many cases, you might need access to some of these module options within your runtime code. We recommend exposing the needed config using Nuxt's [`runtimeConfig`](/docs/4.x/api/nuxt-config#runtimeconfig).
33
+
34
+ <!-- TODO: Update after #18466 (or equivalent) -->
35
+
36
+ ```js
37
+ import { defineNuxtModule } from '@nuxt/kit'
38
+ import { defu } from 'defu'
39
+
40
+ export default defineNuxtModule({
41
+ setup (options, nuxt) {
42
+ nuxt.options.runtimeConfig.public.myModule = defu(nuxt.options.runtimeConfig.public.myModule, {
43
+ foo: options.foo,
44
+ })
45
+ },
46
+ })
47
+ ```
48
+
49
+ Note that we use [`defu`](https://github.com/unjs/defu) to extend the public runtime configuration the user provides instead of overwriting it.
50
+
51
+ You can then access your module options in a plugin, component, the application like any other runtime configuration:
52
+
53
+ ```js
54
+ import { useRuntimeConfig } from '@nuxt/kit'
55
+
56
+ const options = useRuntimeConfig().public.myModule
57
+ ```
58
+
59
+ ::warning
60
+ Be careful not to expose any sensitive module configuration on the public runtime config, such as private API keys, as they will end up in the public bundle.
61
+ ::
62
+
63
+ :read-more{to="/docs/4.x/guide/going-further/runtime-config"}
64
+
65
+ ::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/passing-and-exposing-module-options?friend=nuxt" target="_blank"}
66
+ Watch Vue School video about passing and exposing Nuxt module options.
67
+ ::
68
+
69
+ ## Add Plugins
70
+
71
+ Plugins are a common way for a module to add runtime logic. You can use the `addPlugin` utility to register them from your module.
72
+
73
+ ```js
74
+ import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
75
+
76
+ export default defineNuxtModule({
77
+ setup (options, nuxt) {
78
+ // Create resolver to resolve relative paths
79
+ const resolver = createResolver(import.meta.url)
80
+
81
+ addPlugin(resolver.resolve('./runtime/plugin'))
82
+ },
83
+ })
84
+ ```
85
+
86
+ :read-more{to="/docs/4.x/guide/going-further/kit"}
87
+
88
+ ## Add Components
89
+
90
+ If your module should provide Vue components, you can use the `addComponent` utility to add them as auto-imports for Nuxt to resolve.
91
+
92
+ ```ts twoslash
93
+ import { addComponent, createResolver, defineNuxtModule, useRuntimeConfig } from '@nuxt/kit'
94
+
95
+ export default defineNuxtModule({
96
+ setup (options, nuxt) {
97
+ const resolver = createResolver(import.meta.url)
98
+
99
+ // From the runtime directory
100
+ addComponent({
101
+ name: 'MySuperComponent', // name of the component to be used in vue templates
102
+ export: 'MySuperComponent', // (optional) if the component is a named (rather than default) export
103
+ filePath: resolver.resolve('runtime/components/MySuperComponent.vue'),
104
+ })
105
+
106
+ // From a library
107
+ addComponent({
108
+ name: 'MyAwesomeComponent', // name of the component to be used in vue templates
109
+ export: 'MyAwesomeComponent', // (optional) if the component is a named (rather than default) export
110
+ filePath: '@vue/awesome-components',
111
+ })
112
+ },
113
+ })
114
+ ```
115
+
116
+ Alternatively, you can add an entire directory by using `addComponentsDir`.
117
+
118
+ ```ts
119
+ import { addComponentsDir, defineNuxtModule } from '@nuxt/kit'
120
+
121
+ export default defineNuxtModule({
122
+ setup (options, nuxt) {
123
+ const resolver = createResolver(import.meta.url)
124
+
125
+ addComponentsDir({
126
+ path: resolver.resolve('runtime/components'),
127
+ })
128
+ },
129
+ })
130
+ ```
131
+
132
+ ::tip{icon="i-lucide-lightbulb"}
133
+ It is highly recommended to prefix your exports to avoid conflicts with user code or other modules.
134
+
135
+ :read-more{to="/docs/4.x/guide/modules/best-practices#prefix-your-exports"}
136
+ ::
137
+
138
+ ## Add Composables
139
+
140
+ If your module should provide composables, you can use the `addImports` utility to add them as auto-imports for Nuxt to resolve.
141
+
142
+ ```ts
143
+ import { addImports, createResolver, defineNuxtModule } from '@nuxt/kit'
144
+
145
+ export default defineNuxtModule({
146
+ setup (options, nuxt) {
147
+ const resolver = createResolver(import.meta.url)
148
+
149
+ addImports({
150
+ name: 'useComposable', // name of the composable to be used
151
+ as: 'useComposable',
152
+ from: resolver.resolve('runtime/composables/useComposable'), // path of composable
153
+ })
154
+ },
155
+ })
156
+ ```
157
+
158
+ Alternatively, you can add an entire directory by using `addImportsDir`.
159
+
160
+ ```ts
161
+ import { addImportsDir, createResolver, defineNuxtModule } from '@nuxt/kit'
162
+
163
+ export default defineNuxtModule({
164
+ setup (options, nuxt) {
165
+ const resolver = createResolver(import.meta.url)
166
+
167
+ addImportsDir(resolver.resolve('runtime/composables'))
168
+ },
169
+ })
170
+ ```
171
+
172
+ ::tip{icon="i-lucide-lightbulb"}
173
+ It is highly recommended to prefix your exports to avoid conflicts with user code or other modules.
174
+
175
+ :read-more{to="/docs/4.x/guide/modules/best-practices#prefix-your-exports"}
176
+ ::
177
+
178
+ ## Add Server Routes
179
+
180
+ ```ts
181
+ import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'
182
+
183
+ export default defineNuxtModule({
184
+ setup (options, nuxt) {
185
+ const resolver = createResolver(import.meta.url)
186
+
187
+ addServerHandler({
188
+ route: '/api/_my-module/hello',
189
+ handler: resolver.resolve('./runtime/server/api/hello/index.get'),
190
+ })
191
+ },
192
+ })
193
+ ```
194
+
195
+ You can also add a dynamic server route:
196
+
197
+ ```ts
198
+ import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'
199
+
200
+ export default defineNuxtModule({
201
+ setup (options, nuxt) {
202
+ const resolver = createResolver(import.meta.url)
203
+
204
+ addServerHandler({
205
+ route: '/api/_my-module/hello/:name',
206
+ handler: resolver.resolve('./runtime/server/api/hello/[name].get'),
207
+ })
208
+ },
209
+ })
210
+ ```
211
+
212
+ ::tip{icon="i-lucide-lightbulb"}
213
+ It is highly recommended to prefix your server routes to avoid conflicts with user-defined routes. Common paths like `/api/auth`, `/api/login`, or `/api/user` may already be used by the application.
214
+
215
+ :read-more{to="/docs/4.x/guide/modules/best-practices#prefix-your-exports"}
216
+ ::
217
+
218
+ ## Add Other Assets
219
+
220
+ If your module should provide other kinds of assets, they can also be injected. Here's a simple example module injecting a stylesheet through Nuxt's `css` array.
221
+
222
+ ```js
223
+ import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
224
+
225
+ export default defineNuxtModule({
226
+ setup (options, nuxt) {
227
+ const resolver = createResolver(import.meta.url)
228
+
229
+ nuxt.options.css.push(resolver.resolve('./runtime/style.css'))
230
+ },
231
+ })
232
+ ```
233
+
234
+ And a more advanced one, exposing a folder of assets through [Nitro](/docs/4.x/guide/concepts/server-engine)'s `publicAssets` option:
235
+
236
+ ```js
237
+ import { createResolver, defineNuxtModule } from '@nuxt/kit'
238
+
239
+ export default defineNuxtModule({
240
+ setup (options, nuxt) {
241
+ const resolver = createResolver(import.meta.url)
242
+
243
+ nuxt.hook('nitro:config', (nitroConfig) => {
244
+ nitroConfig.publicAssets ||= []
245
+ nitroConfig.publicAssets.push({
246
+ dir: resolver.resolve('./runtime/public'),
247
+ maxAge: 60 * 60 * 24 * 365, // 1 year
248
+ })
249
+ })
250
+ },
251
+ })
252
+ ```
253
+
254
+ ## Use Other Modules
255
+
256
+ If your module depends on other modules, you can specify them using the `moduleDependencies` option. This provides a more robust way to handle module dependencies with version constraints and configuration merging:
257
+
258
+ ```ts
259
+ import { createResolver, defineNuxtModule } from '@nuxt/kit'
260
+
261
+ const resolver = createResolver(import.meta.url)
262
+
263
+ export default defineNuxtModule<ModuleOptions>({
264
+ meta: {
265
+ name: 'my-module',
266
+ },
267
+ moduleDependencies: {
268
+ '@nuxtjs/tailwindcss': {
269
+ // You can specify a version constraint for the module
270
+ version: '>=6',
271
+ // Any configuration that should override `nuxt.options`
272
+ overrides: {
273
+ exposeConfig: true,
274
+ },
275
+ // Any configuration that should be set. It will override module defaults but
276
+ // will not override any configuration set in `nuxt.options`
277
+ defaults: {
278
+ config: {
279
+ darkMode: 'class',
280
+ content: {
281
+ files: [
282
+ resolver.resolve('./runtime/components/**/*.{vue,mjs,ts}'),
283
+ resolver.resolve('./runtime/*.{mjs,js,ts}'),
284
+ ],
285
+ },
286
+ },
287
+ },
288
+ },
289
+ },
290
+ setup (options, nuxt) {
291
+ // We can inject our CSS file which includes Tailwind's directives
292
+ nuxt.options.css.push(resolver.resolve('./runtime/assets/styles.css'))
293
+ },
294
+ })
295
+ ```
296
+
297
+ ::callout{type="info"}
298
+ The `moduleDependencies` option replaces the deprecated `installModule` function and ensures proper setup order and configuration merging.
299
+ ::
@@ -0,0 +1,231 @@
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
+ ```
@@ -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.