@nuxt/docs 3.17.6 → 3.17.7
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/18.upgrade.md +59 -1
- package/2.guide/2.directory-structure/2.env.md +4 -0
- package/2.guide/3.going-further/1.events.md +3 -22
- package/2.guide/3.going-further/2.hooks.md +21 -2
- package/2.guide/3.going-further/3.modules.md +25 -0
- package/3.api/2.composables/use-async-data.md +3 -3
- package/3.api/2.composables/use-fetch.md +8 -7
- package/3.api/2.composables/use-nuxt-data.md +1 -1
- package/3.api/2.composables/use-runtime-config.md +1 -1
- package/package.json +1 -1
|
@@ -299,6 +299,64 @@ export default defineNuxtConfig({
|
|
|
299
299
|
})
|
|
300
300
|
```
|
|
301
301
|
|
|
302
|
+
### Corrected Module Loading Order in Layers
|
|
303
|
+
|
|
304
|
+
🚦 **Impact Level**: Minimal
|
|
305
|
+
|
|
306
|
+
#### What Changed
|
|
307
|
+
|
|
308
|
+
The order in which modules are loaded when using [Nuxt layers](/docs/guide/going-further/layers) has been corrected. Previously, modules from the project root were loaded before modules from extended layers, which was the reverse of the expected behavior.
|
|
309
|
+
|
|
310
|
+
Now modules are loaded in the correct order:
|
|
311
|
+
|
|
312
|
+
1. **Layer modules first** (in extend order - deeper layers first)
|
|
313
|
+
2. **Project modules last** (highest priority)
|
|
314
|
+
|
|
315
|
+
This affects both:
|
|
316
|
+
* Modules defined in the `modules` array in `nuxt.config.ts`
|
|
317
|
+
* Auto-discovered modules from the `modules/` directory
|
|
318
|
+
|
|
319
|
+
#### Reasons for Change
|
|
320
|
+
|
|
321
|
+
This change ensures that:
|
|
322
|
+
* Extended layers have lower priority than the consuming project
|
|
323
|
+
* Module execution order matches the intuitive layer inheritance pattern
|
|
324
|
+
* Module configuration and hooks work as expected in multi-layer setups
|
|
325
|
+
|
|
326
|
+
#### Migration Steps
|
|
327
|
+
|
|
328
|
+
**Most projects will not need changes**, as this corrects the loading order to match expected behavior.
|
|
329
|
+
|
|
330
|
+
However, if your project was relying on the previous incorrect order, you may need to:
|
|
331
|
+
|
|
332
|
+
1. **Review module dependencies**: Check if any modules depend on specific loading order
|
|
333
|
+
2. **Adjust module configuration**: If modules were configured to work around the incorrect order
|
|
334
|
+
3. **Test thoroughly**: Ensure all functionality works as expected with the corrected order
|
|
335
|
+
|
|
336
|
+
Example of the new correct order:
|
|
337
|
+
```ts
|
|
338
|
+
// Layer: my-layer/nuxt.config.ts
|
|
339
|
+
export default defineNuxtConfig({
|
|
340
|
+
modules: ['layer-module-1', 'layer-module-2']
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
// Project: nuxt.config.ts
|
|
344
|
+
export default defineNuxtConfig({
|
|
345
|
+
extends: ['./my-layer'],
|
|
346
|
+
modules: ['project-module-1', 'project-module-2']
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
// Loading order (corrected):
|
|
350
|
+
// 1. layer-module-1
|
|
351
|
+
// 2. layer-module-2
|
|
352
|
+
// 3. project-module-1 (can override layer modules)
|
|
353
|
+
// 4. project-module-2 (can override layer modules)
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
If you encounter issues with module order dependencies due to needing to register a hook, consider using the [`modules:done` hook](/docs/guide/going-further/modules#custom-hooks) for modules that need to call a hook. This is run after all other modules have been loaded, which means it is safe to use.
|
|
357
|
+
|
|
358
|
+
👉 See [PR #31507](https://github.com/nuxt/nuxt/pull/31507) and [issue #25719](https://github.com/nuxt/nuxt/issues/25719) for more details.
|
|
359
|
+
|
|
302
360
|
### Deduplication of Route Metadata
|
|
303
361
|
|
|
304
362
|
🚦 **Impact Level**: Minimal
|
|
@@ -777,7 +835,7 @@ This change should generally improve the expected behavior, but if you were expe
|
|
|
777
835
|
query: { id },
|
|
778
836
|
immediate: false
|
|
779
837
|
)
|
|
780
|
-
+ watch(id, execute, { once: true })
|
|
838
|
+
+ watch(id, () => execute(), { once: true })
|
|
781
839
|
```
|
|
782
840
|
|
|
783
841
|
To opt out of this behavior:
|
|
@@ -55,6 +55,10 @@ Since `.env` files are not used in production, you must explicitly set environme
|
|
|
55
55
|
|
|
56
56
|
* Many cloud service providers, such as Vercel, Netlify, and AWS, provide interfaces for setting environment variables via their dashboards, CLI tools or configuration files.
|
|
57
57
|
|
|
58
|
+
::important
|
|
59
|
+
`runtimeConfig` [won't pick up environment variables that don't start with `NUXT_` in production] (https://nuxt.com/docs/guide/going-further/runtime-config#environment-variables).
|
|
60
|
+
::
|
|
61
|
+
|
|
58
62
|
## Production Preview
|
|
59
63
|
|
|
60
64
|
For local production preview purpose, we recommend using [`nuxt preview`](/docs/api/commands/preview) since using this command, the `.env` file will be loaded into `process.env` for convenience. Note that this command requires dependencies to be installed in the package directory.
|
|
@@ -58,25 +58,6 @@ await nuxtApp.callHook('app:user:registered', {
|
|
|
58
58
|
You can inspect all events using the **Nuxt DevTools** Hooks panel.
|
|
59
59
|
::
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
```
|
|
61
|
+
::read-more{to="/docs/guide/going-further/hooks"}
|
|
62
|
+
Learn more about Nuxt's built-in hooks and how to extend them
|
|
63
|
+
::
|
|
@@ -74,6 +74,25 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
74
74
|
Learn more about available Nitro lifecycle hooks.
|
|
75
75
|
::
|
|
76
76
|
|
|
77
|
-
##
|
|
77
|
+
## Adding Custom Hooks
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
You can define your own custom hooks support by extending Nuxt's hook interfaces.
|
|
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
|
+
```
|
|
@@ -559,6 +559,31 @@ export default defineNuxtModule({
|
|
|
559
559
|
```
|
|
560
560
|
::
|
|
561
561
|
|
|
562
|
+
##### Custom Hooks
|
|
563
|
+
|
|
564
|
+
Modules can also define and call their own hooks, which is a powerful pattern for making your module extensible.
|
|
565
|
+
|
|
566
|
+
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.
|
|
567
|
+
|
|
568
|
+
```ts
|
|
569
|
+
// my-module/module.ts
|
|
570
|
+
import { defineNuxtModule } from '@nuxt/kit'
|
|
571
|
+
|
|
572
|
+
export interface ModuleHooks {
|
|
573
|
+
'my-module:custom-hook': (payload: { foo: string }) => void
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export default defineNuxtModule({
|
|
577
|
+
setup (options, nuxt) {
|
|
578
|
+
// Call your hook in `modules:done`
|
|
579
|
+
nuxt.hook('modules:done', async () => {
|
|
580
|
+
const payload = { foo: 'bar' }
|
|
581
|
+
await nuxt.callHook('my-module:custom-hook', payload)
|
|
582
|
+
})
|
|
583
|
+
}
|
|
584
|
+
})
|
|
585
|
+
```
|
|
586
|
+
|
|
562
587
|
#### Adding Templates/Virtual Files
|
|
563
588
|
|
|
564
589
|
If you need to add a virtual file that can be imported into the user's app, you can use the `addTemplate` utility.
|
|
@@ -159,7 +159,7 @@ const { data: users2 } = useAsyncData('users', () => $fetch('/api/users'), { imm
|
|
|
159
159
|
By default, Nuxt waits until a `refresh` is finished before it can be executed again.
|
|
160
160
|
|
|
161
161
|
::note
|
|
162
|
-
If you have not fetched data on the server (for example, with `server: false`), then the data _will not_ be fetched until hydration completes. This means even if you await [`useAsyncData`](/docs/api/composables/use-async-data) on the client side, `data` will remain `
|
|
162
|
+
If you have not fetched data on the server (for example, with `server: false`), then the data _will not_ be fetched until hydration completes. This means even if you await [`useAsyncData`](/docs/api/composables/use-async-data) on the client side, `data` will remain `undefined` within `<script setup>`.
|
|
163
163
|
::
|
|
164
164
|
|
|
165
165
|
## Type
|
|
@@ -170,7 +170,7 @@ function useAsyncData<DataT, DataE>(
|
|
|
170
170
|
options?: AsyncDataOptions<DataT>
|
|
171
171
|
): AsyncData<DataT, DataE>
|
|
172
172
|
function useAsyncData<DataT, DataE>(
|
|
173
|
-
key:
|
|
173
|
+
key: MaybeRefOrGetter<string>,
|
|
174
174
|
handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
|
|
175
175
|
options?: AsyncDataOptions<DataT>
|
|
176
176
|
): Promise<AsyncData<DataT, DataE>>
|
|
@@ -184,7 +184,7 @@ type AsyncDataOptions<DataT> = {
|
|
|
184
184
|
default?: () => DataT | Ref<DataT> | null
|
|
185
185
|
transform?: (input: DataT) => DataT | Promise<DataT>
|
|
186
186
|
pick?: string[]
|
|
187
|
-
watch?:
|
|
187
|
+
watch?: MultiWatchSources | false
|
|
188
188
|
getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
|
|
189
189
|
}
|
|
190
190
|
|
|
@@ -103,7 +103,7 @@ function useFetch<DataT, ErrorT>(
|
|
|
103
103
|
): Promise<AsyncData<DataT, ErrorT>>
|
|
104
104
|
|
|
105
105
|
type UseFetchOptions<DataT> = {
|
|
106
|
-
key?: string
|
|
106
|
+
key?: MaybeRefOrGetter<string>
|
|
107
107
|
method?: string
|
|
108
108
|
query?: SearchParams
|
|
109
109
|
params?: SearchParams
|
|
@@ -119,7 +119,8 @@ type UseFetchOptions<DataT> = {
|
|
|
119
119
|
default?: () => DataT
|
|
120
120
|
transform?: (input: DataT) => DataT | Promise<DataT>
|
|
121
121
|
pick?: string[]
|
|
122
|
-
|
|
122
|
+
$fetch?: typeof globalThis.$fetch
|
|
123
|
+
watch?: MultiWatchSources | false
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
type AsyncDataRequestContext = {
|
|
@@ -151,7 +152,7 @@ type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
|
|
|
151
152
|
|
|
152
153
|
| Option | Type | Default | Description |
|
|
153
154
|
| ---| --- | --- | --- |
|
|
154
|
-
| `key` | `string
|
|
155
|
+
| `key` | `MaybeRefOrGetter<string>` | auto-gen | Unique key for de-duplication. If not provided, generated from URL and options. |
|
|
155
156
|
| `method` | `string` | `'GET'` | HTTP request method. |
|
|
156
157
|
| `query` | `object` | - | Query/search params to append to the URL. Alias: `params`. Supports refs/computed. |
|
|
157
158
|
| `params` | `object` | - | Alias for `query`. |
|
|
@@ -167,10 +168,10 @@ type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
|
|
|
167
168
|
| `transform` | `(input: DataT) => DataT \| Promise<DataT>` | - | Function to transform the result after resolving. |
|
|
168
169
|
| `getCachedData`| `(key, nuxtApp, ctx) => DataT \| undefined` | - | Function to return cached data. See below for default. |
|
|
169
170
|
| `pick` | `string[]` | - | Only pick specified keys from the result. |
|
|
170
|
-
| `watch` | `
|
|
171
|
+
| `watch` | `MultiWatchSources \| false` | - | Array of reactive sources to watch and auto-refresh. `false` disables watching. |
|
|
171
172
|
| `deep` | `boolean` | `false` | Return data in a deep ref object. |
|
|
172
173
|
| `dedupe` | `'cancel' \| 'defer'` | `'cancel'` | Avoid fetching same key more than once at a time. |
|
|
173
|
-
| `$fetch` | `typeof
|
|
174
|
+
| `$fetch` | `typeof globalThis.$fetch` | - | Custom $fetch implementation. |
|
|
174
175
|
|
|
175
176
|
::note
|
|
176
177
|
All fetch options can be given a `computed` or `ref` value. These will be watched and new requests made automatically with any new values if they are updated.
|
|
@@ -189,10 +190,10 @@ This only caches data when `experimental.payloadExtraction` in `nuxt.config` is
|
|
|
189
190
|
|
|
190
191
|
| Name | Type | Description |
|
|
191
192
|
| --- | --- |--- |
|
|
192
|
-
| `data` | `Ref<DataT \|
|
|
193
|
+
| `data` | `Ref<DataT \| undefined>` | The result of the asynchronous fetch. |
|
|
193
194
|
| `refresh` | `(opts?: AsyncDataExecuteOptions) => Promise<void>` | Function to manually refresh the data. By default, Nuxt waits until a `refresh` is finished before it can be executed again. |
|
|
194
195
|
| `execute` | `(opts?: AsyncDataExecuteOptions) => Promise<void>` | Alias for `refresh`. |
|
|
195
|
-
| `error` | `Ref<ErrorT \|
|
|
196
|
+
| `error` | `Ref<ErrorT \| undefined>` | Error object if the data fetching failed. |
|
|
196
197
|
| `status` | `Ref<'idle' \| 'pending' \| 'success' \| 'error'>` | Status of the data request. See below for possible values. |
|
|
197
198
|
| `clear` | `() => void` | Resets `data` to `undefined` (or the value of `options.default()` if provided), `error` to `null`, set `status` to `idle`, and cancels any pending requests. |
|
|
198
199
|
|
|
@@ -55,7 +55,7 @@ Variables that need to be accessible on the server are added directly inside `ru
|
|
|
55
55
|
To access runtime config, we can use `useRuntimeConfig()` composable:
|
|
56
56
|
|
|
57
57
|
```ts [server/api/test.ts]
|
|
58
|
-
export default defineEventHandler((event) => {
|
|
58
|
+
export default defineEventHandler(async (event) => {
|
|
59
59
|
const config = useRuntimeConfig(event)
|
|
60
60
|
|
|
61
61
|
// Access public variables
|