@nuxt/docs 3.17.1 → 3.17.2

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.
@@ -131,7 +131,7 @@ definePageMeta({
131
131
 
132
132
  Nuxt offers route validation via the `validate` property in [`definePageMeta()`](/docs/api/utils/define-page-meta) in each page you wish to validate.
133
133
 
134
- The `validate` property accepts the `route` as an argument. You can return a boolean value to determine whether or not this is a valid route to be rendered with this page. If you return `false`, and another match can't be found, this will cause a 404 error. You can also directly return an object with `statusCode`/`statusMessage` to respond immediately with an error (other matches will not be checked).
134
+ The `validate` property accepts the `route` as an argument. You can return a boolean value to determine whether or not this is a valid route to be rendered with this page. If you return `false`, this will cause a 404 error. You can also directly return an object with `statusCode`/`statusMessage` to customize the error returned.
135
135
 
136
136
  If you have a more complex use case, then you can use anonymous route middleware instead.
137
137
 
@@ -76,6 +76,7 @@ export default defineNuxtConfig({
76
76
  // spaLoadingTemplateLocation: 'within',
77
77
  // parseErrorData: false,
78
78
  // pendingWhenIdle: true,
79
+ // alwaysRunFetchOnKeyChange: true,
79
80
  // defaults: {
80
81
  // useAsyncData: {
81
82
  // deep: true
@@ -752,6 +753,46 @@ export default defineNuxtConfig({
752
753
  })
753
754
  ```
754
755
 
756
+ ### Key Change Behavior in `useAsyncData` and `useFetch`
757
+
758
+ 🚦 **Impact Level**: Medium
759
+
760
+ #### What Changed
761
+
762
+ When using reactive keys in `useAsyncData` or `useFetch`, Nuxt automatically refetches data when the key changes. When `immediate: false` is set, `useAsyncData` will only fetch data when the key changes if the data has already been fetched once.
763
+
764
+ Previously, `useFetch` had slightly different behavior. It would always fetch data when the key changed.
765
+
766
+ Now, `useFetch` and `useAsyncData` behave consistently - by only fetch data when the key changes if the data has already been fetched once.
767
+
768
+ #### Reasons for Change
769
+
770
+ This ensures consistent behavior between `useAsyncData` and `useFetch`, and prevents unexpected fetches. If you have set `immediate: false`, then you must call `refresh` or `execute` or data will never be fetched in `useFetch` or `useAsyncData`.
771
+
772
+ #### Migration Steps
773
+
774
+ This change should generally improve the expected behavior, but if you were expecting changing the key or options of a non-immediate `useFetch`, you now will need to trigger it manually the first time.
775
+
776
+ ```diff
777
+ const id = ref('123')
778
+ const { data, execute } = await useFetch('/api/test', {
779
+ query: { id },
780
+ immediate: false
781
+ )
782
+ + watch(id, execute, { once: true })
783
+ ```
784
+
785
+ To opt out of this behavior:
786
+
787
+ ```ts
788
+ // Or globally in your Nuxt config
789
+ export default defineNuxtConfig({
790
+ experimental: {
791
+ alwaysRunFetchOnKeyChange: true
792
+ }
793
+ })
794
+ ```
795
+
755
796
  ### Shallow Data Reactivity in `useAsyncData` and `useFetch`
756
797
 
757
798
  🚦 **Impact Level**: Minimal
@@ -54,7 +54,7 @@ const double = computed(() => count.value * 2)
54
54
 
55
55
  When you are using the built-in Composition API composables provided by Vue and Nuxt, be aware that many of them rely on being called in the right _context_.
56
56
 
57
- During a component lifecycle, Vue tracks the temporary instance of the current component (and similarly, Nuxt tracks a temporary instance of `nuxtApp`) via a global variable, and then unsets it in same tick. This is essential when server rendering, both to avoid cross-request state pollution (leaking a shared reference between two users) and to avoid leakage between different components.
57
+ During a component lifecycle, Vue tracks the temporary instance of the current component (and similarly, Nuxt tracks a temporary instance of `nuxtApp`) via a global variable, and then unsets it in the same tick. This is essential when server rendering, both to avoid cross-request state pollution (leaking a shared reference between two users) and to avoid leakage between different components.
58
58
 
59
59
  That means that (with very few exceptions) you cannot use them outside a Nuxt plugin, Nuxt route middleware or Vue setup function. On top of that, you must use them synchronously - that is, you cannot use `await` before calling a composable, except within `<script setup>` blocks, within the setup function of a component declared with `defineNuxtComponent`, in `defineNuxtPlugin` or in `defineNuxtRouteMiddleware`, where we perform a transform to keep the synchronous context even after the `await`.
60
60
 
@@ -0,0 +1,82 @@
1
+ ---
2
+ title: "Events"
3
+ description: "Nuxt provides a powerful event system powered by hookable."
4
+ ---
5
+
6
+ # Events
7
+
8
+ 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
+
10
+ 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.
11
+
12
+ ## Creating Events and Listeners
13
+
14
+ You can create your own custom events using the `hook` method:
15
+
16
+ ```ts
17
+ const nuxtApp = useNuxtApp()
18
+
19
+ nuxtApp.hook('app:user:registered', payload => {
20
+ console.log('A new user has registered!', payload)
21
+ })
22
+ ```
23
+
24
+ To emit an event and notify any listeners, use `callHook`:
25
+
26
+ ```ts
27
+ const nuxtApp = useNuxtApp()
28
+
29
+ await nuxtApp.callHook('app:user:registered', {
30
+ id: 1,
31
+ name: 'John Doe',
32
+ })
33
+ ```
34
+
35
+ You can also use the payload object to enable two-way communication between the emitter and listeners. Since the payload is passed by reference, a listener can modify it to send data back to the emitter.
36
+
37
+ ```ts
38
+ const nuxtApp = useNuxtApp()
39
+
40
+ nuxtApp.hook('app:user:registered', payload => {
41
+ payload.message = 'Welcome to our app!'
42
+ })
43
+
44
+ const payload = {
45
+ id: 1,
46
+ name: 'John Doe',
47
+ }
48
+
49
+ await nuxtApp.callHook('app:user:registered', {
50
+ id: 1,
51
+ name: 'John Doe',
52
+ })
53
+
54
+ // payload.message will be 'Welcome to our app!'
55
+ ```
56
+
57
+ ::tip
58
+ You can inspect all events using the **Nuxt DevTools** Hooks panel.
59
+ ::
60
+
61
+ ## Augmenting Types
62
+
63
+ You can augment the types of hooks provided by Nuxt.
64
+
65
+ ```ts
66
+ import { HookResult } from "@nuxt/schema";
67
+
68
+ declare module '#app' {
69
+ interface RuntimeNuxtHooks {
70
+ 'your-nuxt-runtime-hook': () => HookResult
71
+ }
72
+ interface NuxtHooks {
73
+ 'your-nuxt-hook': () => HookResult
74
+ }
75
+ }
76
+
77
+ declare module 'nitropack' {
78
+ interface NitroRuntimeHooks {
79
+ 'your-nitro-hook': () => void;
80
+ }
81
+ }
82
+ ```
@@ -76,23 +76,4 @@ Learn more about available Nitro lifecycle hooks.
76
76
 
77
77
  ## Additional Hooks
78
78
 
79
- You can add additional hooks by augmenting the types provided by Nuxt. This can be useful for modules.
80
-
81
- ```ts
82
- import { HookResult } from "@nuxt/schema";
83
-
84
- declare module '#app' {
85
- interface RuntimeNuxtHooks {
86
- 'your-nuxt-runtime-hook': () => HookResult
87
- }
88
- interface NuxtHooks {
89
- 'your-nuxt-hook': () => HookResult
90
- }
91
- }
92
-
93
- declare module 'nitropack' {
94
- interface NitroRuntimeHooks {
95
- 'your-nitro-hook': () => void;
96
- }
97
- }
98
- ```
79
+ Learn more about creating custom hooks in the [Events section](/docs/guide/going-further/events).
@@ -14,87 +14,57 @@ Modules are the building blocks of Nuxt. Kit provides a set of utilities to help
14
14
 
15
15
  Define a Nuxt module, automatically merging defaults with user provided options, installing any hooks that are provided, and calling an optional setup function for full control.
16
16
 
17
- ### Type
17
+ ### Usage
18
18
 
19
- ```ts
20
- function defineNuxtModule<OptionsT extends ModuleOptions> (definition: ModuleDefinition<OptionsT> | NuxtModule<OptionsT>): NuxtModule<OptionsT>
21
-
22
- type ModuleOptions = Record<string, any>
23
-
24
- interface ModuleDefinition<T extends ModuleOptions = ModuleOptions> {
25
- meta?: ModuleMeta
26
- defaults?: T | ((nuxt: Nuxt) => T)
27
- schema?: T
28
- hooks?: Partial<NuxtHooks>
29
- setup?: (this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void | false | ModuleSetupReturn>
30
- }
31
-
32
- interface NuxtModule<T extends ModuleOptions = ModuleOptions> {
33
- (this: void, inlineOptions: T, nuxt: Nuxt): Awaitable<void | false | ModuleSetupReturn>
34
- getOptions?: (inlineOptions?: T, nuxt?: Nuxt) => Promise<T>
35
- getMeta?: () => Promise<ModuleMeta>
36
- }
37
-
38
- interface ModuleSetupReturn {
39
- timings?: {
40
- setup?: number
41
- [key: string]: number | undefined
19
+ ```ts twoslash
20
+ import { defineNuxtModule } from '@nuxt/kit'
21
+
22
+ export default defineNuxtModule({
23
+ meta: {
24
+ name: 'my-module',
25
+ configKey: 'myModule'
26
+ },
27
+ defaults: {
28
+ enabled: true
29
+ },
30
+ setup (options) {
31
+ if (options.enabled) {
32
+ console.log('My Nuxt module is enabled!')
33
+ }
42
34
  }
43
- }
44
-
45
- interface ModuleMeta {
46
- name?: string
47
- version?: string
48
- configKey?: string
49
- compatibility?: NuxtCompatibility
50
- [key: string]: unknown
51
- }
35
+ })
52
36
  ```
53
37
 
54
- ### Parameters
55
-
56
- #### `definition`
57
-
58
- **Type**: `ModuleDefinition<T> | NuxtModule<T>`
59
-
60
- **Required**: `true`
61
-
62
- A module definition object or a module function.
63
-
64
- - `meta` (optional)
65
-
66
- **Type**: `ModuleMeta`
67
-
68
- Metadata of the module. It defines the module name, version, config key and compatibility.
69
-
70
- - `defaults` (optional)
71
-
72
- **Type**: `T | ((nuxt: Nuxt) => T)`
73
-
74
- Default options for the module. If a function is provided, it will be called with the Nuxt instance as the first argument.
75
-
76
- - `schema` (optional)
77
-
78
- **Type**: `T`
79
-
80
- Schema for the module options. If provided, options will be applied to the schema.
38
+ ### Type
81
39
 
82
- - `hooks` (optional)
40
+ ```ts twoslash
41
+ // @errors: 2391
42
+ import type { ModuleDefinition, ModuleOptions, NuxtModule } from '@nuxt/schema'
43
+ // ---cut---
44
+ export function defineNuxtModule<TOptions extends ModuleOptions> (
45
+ definition?: ModuleDefinition<TOptions, Partial<TOptions>, false> | NuxtModule<TOptions, Partial<TOptions>, false>,
46
+ ): NuxtModule<TOptions, TOptions, false>
47
+ ```
83
48
 
84
- **Type**: `Partial<NuxtHooks>`
49
+ ### Parameters
85
50
 
86
- Hooks to be installed for the module. If provided, the module will install the hooks.
51
+ **definition**: A module definition object or a module function. The module definition object should contain the following properties:
87
52
 
88
- - `setup` (optional)
53
+ | Property | Type | Required | Description |
54
+ | ------------------ | -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
55
+ | `meta` | `ModuleMeta` | `false` | Metadata of the module. It defines the module name, version, config key and compatibility. |
56
+ | `defaults` | `T \| ((nuxt: Nuxt) => T)`{lang="ts"} | `false` | Default options for the module. If a function is provided, it will be called with the Nuxt instance as the first argument. |
57
+ | `schema` | `T` | `false` | Schema for the module options. If provided, options will be applied to the schema. |
58
+ | `hooks` | `Partial<NuxtHooks>`{lang="ts"} | `false` | Hooks to be installed for the module. If provided, the module will install the hooks. |
59
+ | `setup` | `(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void \| false \| ModuleSetupInstallResult>`{lang="ts"} | `false` | Setup function for the module. If provided, the module will call the setup function. |
89
60
 
90
- **Type**: `(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void | false | ModuleSetupReturn>`
61
+ ### Examples
91
62
 
92
- Setup function for the module. If provided, the module will call the setup function.
63
+ #### Using `configKey` to Make Your Module Configurable
93
64
 
94
- ### Examples
65
+ When defining a Nuxt module, you can set a `configKey` to specify how users should configure the module in their `nuxt.config`.
95
66
 
96
67
  ```ts
97
- // https://github.com/nuxt/starter/tree/module
98
68
  import { defineNuxtModule } from '@nuxt/kit'
99
69
 
100
70
  export default defineNuxtModule({
@@ -103,51 +73,94 @@ export default defineNuxtModule({
103
73
  configKey: 'myModule'
104
74
  },
105
75
  defaults: {
106
- test: 123
76
+ // Module options
77
+ enabled: true
107
78
  },
108
- setup (options, nuxt) {
109
- nuxt.hook('modules:done', () => {
110
- console.log('My module is ready with current test option: ', options.test)
111
- })
79
+ setup (options) {
80
+ if (options.enabled) {
81
+ console.log('My Nuxt module is enabled!')
82
+ }
112
83
  }
113
84
  })
114
85
  ```
115
86
 
116
- ## `installModule`
117
-
118
- Install specified Nuxt module programmatically. This is helpful when your module depends on other modules. You can pass the module options as an object to `inlineOptions` and they will be passed to the module's `setup` function.
119
-
120
- ### Type
87
+ Users can provide options for this module under the corresponding key in `nuxt.config`.
121
88
 
122
89
  ```ts
123
- async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt)
90
+ export default defineNuxtConfig({
91
+ myModule: {
92
+ enabled: false
93
+ }
94
+ })
124
95
  ```
125
96
 
126
- ### Parameters
97
+ #### Defining Module Compatibility Requirements
98
+
99
+ If you're developing a Nuxt module and using APIs that are only supported in specific Nuxt versions, it's highly recommended to include `compatibility.nuxt`.
127
100
 
128
- #### `moduleToInstall`
101
+ ```ts
102
+ export default defineNuxtModule({
103
+ meta: {
104
+ name: '@nuxt/icon',
105
+ configKey: 'icon',
106
+ compatibility: {
107
+ // Required nuxt version in semver format.
108
+ nuxt: '>=3.0.0', // or use '^3.0.0'
109
+ },
110
+ },
111
+ async setup() {
112
+ const resolver = createResolver(import.meta.url)
113
+ // Implement
114
+ },
115
+ })
116
+ ```
129
117
 
130
- **Type**: `string` | `NuxtModule`
118
+ If the user tries to use your module with an incompatible Nuxt version, they will receive a warning in the console.
131
119
 
132
- **Required**: `true`
120
+ ```terminal
121
+ WARN Module @nuxt/icon is disabled due to incompatibility issues:
122
+ - [nuxt] Nuxt version ^3.1.0 is required but currently using 3.0.0
123
+ ```
133
124
 
134
- The module to install. Can be either a string with the module name or a module object itself.
125
+ ## `installModule`
135
126
 
136
- #### `inlineOptions`
127
+ Install specified Nuxt module programmatically. This is helpful when your module depends on other modules. You can pass the module options as an object to `inlineOptions` and they will be passed to the module's `setup` function.
137
128
 
138
- **Type**: `any`
129
+ ### Usage
139
130
 
140
- **Default**: `{}`
131
+ ```ts twoslash
132
+ import { defineNuxtModule, installModule } from '@nuxt/kit'
141
133
 
142
- An object with the module options to be passed to the module's `setup` function.
134
+ export default defineNuxtModule({
135
+ async setup () {
136
+ // will install @nuxtjs/fontaine with Roboto font and Impact fallback
137
+ await installModule('@nuxtjs/fontaine', {
138
+ // module configuration
139
+ fonts: [
140
+ {
141
+ family: 'Roboto',
142
+ fallbacks: ['Impact'],
143
+ fallbackName: 'fallback-a',
144
+ }
145
+ ]
146
+ })
147
+ }
148
+ })
149
+ ```
143
150
 
144
- #### `nuxt`
151
+ ### Type
145
152
 
146
- **Type**: `Nuxt`
153
+ ```ts
154
+ async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt)
155
+ ```
147
156
 
148
- **Default**: `useNuxt()`
157
+ ### Parameters
149
158
 
150
- Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
159
+ | Property | Type | Required | Description |
160
+ | ------------------ | -------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
161
+ | `moduleToInstall` | `string \| NuxtModule`{lang="ts"} | `true` | The module to install. Can be either a string with the module name or a module object itself. |
162
+ | `inlineOptions` | `any` | `false` | An object with the module options to be passed to the module's `setup` function. |
163
+ | `nuxt` | `Nuxt` | `false` | Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. |
151
164
 
152
165
  ### Examples
153
166
 
@@ -22,6 +22,8 @@ function useRuntimeConfig (): Record<string, unknown>
22
22
 
23
23
  It is also possible to update runtime configuration. This will be merged with the existing runtime configuration, and if Nitro has already been initialized it will trigger an HMR event to reload the Nitro runtime config.
24
24
 
25
+ ### Type
26
+
25
27
  ```ts
26
28
  function updateRuntimeConfig (config: Record<string, unknown>): void | Promise<void>
27
29
  ```