@nuxt/docs-nightly 4.4.0-29533491.7793caf5 → 4.4.0-29533707.0a5a5c19
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 +55 -2
- package/3.guide/6.going-further/1.experimental-features.md +5 -0
- package/4.api/1.components/12.nuxt-route-announcer.md +4 -0
- package/4.api/1.components/14.nuxt-announcer.md +81 -0
- package/4.api/2.composables/use-announcer.md +128 -0
- package/4.api/2.composables/use-route-announcer.md +4 -0
- package/4.api/3.utils/clear-nuxt-state.md +4 -2
- package/package.json +1 -1
|
@@ -59,6 +59,7 @@ export default defineNuxtConfig({
|
|
|
59
59
|
When you set your `future.compatibilityVersion` to `5`, defaults throughout your Nuxt configuration will change to opt in to Nuxt v5 behavior, including:
|
|
60
60
|
|
|
61
61
|
- **Vite Environment API**: Automatically enables the new [Vite Environment API](/docs/4.x/getting-started/upgrade#migration-to-vite-environment-api) for improved build configuration
|
|
62
|
+
- **`clearNuxtState` resets to defaults**: `clearNuxtState` will [reset state to its initial value](/docs/4.x/getting-started/upgrade#respect-defaults-when-clearing-usestate) instead of setting it to `undefined`
|
|
62
63
|
- Other Nuxt 5 improvements and changes as they become available
|
|
63
64
|
|
|
64
65
|
::note
|
|
@@ -272,6 +273,7 @@ Nuxt now defaults to a new directory structure, with backwards compatibility (so
|
|
|
272
273
|
- `layers/`, `modules/` and `public/` are resolved relative to `<rootDir>` by default
|
|
273
274
|
- if using [Nuxt Content v2.13+](https://github.com/nuxt/content/pull/2649), `content/` is resolved relative to `<rootDir>`
|
|
274
275
|
- a new `dir.app` is added, which is the directory we look for `router.options.ts` and `spa-loading-template.html` - this defaults to `<srcDir>/`
|
|
276
|
+
- a new [`shared/`](/docs/4.x/directory-structure/shared) directory is available for code shared between the Vue app and the Nitro server, with auto-imports for `shared/utils/` and `shared/types/`
|
|
275
277
|
|
|
276
278
|
<details>
|
|
277
279
|
|
|
@@ -298,6 +300,8 @@ modules/
|
|
|
298
300
|
node_modules/
|
|
299
301
|
public/
|
|
300
302
|
shared/
|
|
303
|
+
types/
|
|
304
|
+
utils/
|
|
301
305
|
server/
|
|
302
306
|
api/
|
|
303
307
|
middleware/
|
|
@@ -326,14 +330,14 @@ With this new structure, the `~` alias now points to the `app/` directory by def
|
|
|
326
330
|
|
|
327
331
|
1. Create a new directory called `app/`.
|
|
328
332
|
1. Move your `assets/`, `components/`, `composables/`, `app/layouts/`, `app/middleware/`, `app/pages/`, `app/plugins/` and `utils/` folders under it, as well as `app.vue`, `error.vue`, `app.config.ts`. If you have an `app/router-options.ts` or `app/spa-loading-template.html`, these paths remain the same.
|
|
329
|
-
1. Make sure your `nuxt.config.ts`, `content/`, `layers/`, `modules/`, `public/` and `server/` folders remain outside the `app/` folder, in the root of your project.
|
|
333
|
+
1. Make sure your `nuxt.config.ts`, `content/`, `layers/`, `modules/`, `public/`, `shared/` and `server/` folders remain outside the `app/` folder, in the root of your project.
|
|
330
334
|
1. Remember to update any third-party configuration files to work with the new directory structure, such as your `tailwindcss` or `eslint` configuration (if required - `@nuxtjs/tailwindcss` should automatically configure `tailwindcss` correctly).
|
|
331
335
|
|
|
332
336
|
::tip
|
|
333
337
|
You can automate this migration by running `npx codemod@latest nuxt/4/file-structure`
|
|
334
338
|
::
|
|
335
339
|
|
|
336
|
-
However, migration is _not required_. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) The one exception is that if you _already_ have a custom `srcDir`. In this case, you should be aware that your `modules/`, `public/` and `server/` folders will be resolved from your `rootDir` rather than from your custom `srcDir`. You can override this by configuring `dir.modules`, `dir.public` and `serverDir` if you need to.
|
|
340
|
+
However, migration is _not required_. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) The one exception is that if you _already_ have a custom `srcDir`. In this case, you should be aware that your `modules/`, `public/`, `shared/` and `server/` folders will be resolved from your `rootDir` rather than from your custom `srcDir`. You can override this by configuring `dir.modules`, `dir.public` and `serverDir` if you need to.
|
|
337
341
|
|
|
338
342
|
You can also force a v3 folder structure with the following configuration:
|
|
339
343
|
|
|
@@ -846,6 +850,55 @@ If you provide a custom `default` value for `useAsyncData`, this will now be use
|
|
|
846
850
|
|
|
847
851
|
Often users set an appropriately empty value, such as an empty array, to avoid the need to check for `null`/`undefined` when iterating over it. This should be respected when resetting/clearing the data.
|
|
848
852
|
|
|
853
|
+
### Respect defaults when clearing `useState`
|
|
854
|
+
|
|
855
|
+
🚦 **Impact Level**: Minimal
|
|
856
|
+
|
|
857
|
+
#### What Changed
|
|
858
|
+
|
|
859
|
+
With `compatibilityVersion: 5`, `clearNuxtState` will reset state to its initial value (provided by the `init` function of `useState`) instead of setting it to `undefined`. This aligns `clearNuxtState` behavior with `clearNuxtData`, which already resets to defaults.
|
|
860
|
+
|
|
861
|
+
#### Reasons for Change
|
|
862
|
+
|
|
863
|
+
When `clearNuxtState` sets state to `undefined`, composables that depend on that state can crash because they expect the state to always have a valid shape (e.g., accessing properties on `undefined`). Resetting to the `init` value ensures state always has a usable default.
|
|
864
|
+
|
|
865
|
+
#### Migration Steps
|
|
866
|
+
|
|
867
|
+
If you rely on `clearNuxtState` setting state to `undefined`, you can explicitly pass `{ reset: false }`:
|
|
868
|
+
|
|
869
|
+
```diff
|
|
870
|
+
- clearNuxtState('myKey')
|
|
871
|
+
+ clearNuxtState('myKey', { reset: false })
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
Alternatively, you can revert to the previous behavior with:
|
|
875
|
+
|
|
876
|
+
```ts twoslash [nuxt.config.ts]
|
|
877
|
+
export default defineNuxtConfig({
|
|
878
|
+
experimental: {
|
|
879
|
+
defaults: {
|
|
880
|
+
useState: {
|
|
881
|
+
resetOnClear: false,
|
|
882
|
+
},
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
})
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
You can also opt in to this behavior today without setting `compatibilityVersion: 5`:
|
|
889
|
+
|
|
890
|
+
```ts twoslash [nuxt.config.ts]
|
|
891
|
+
export default defineNuxtConfig({
|
|
892
|
+
experimental: {
|
|
893
|
+
defaults: {
|
|
894
|
+
useState: {
|
|
895
|
+
resetOnClear: true,
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
},
|
|
899
|
+
})
|
|
900
|
+
```
|
|
901
|
+
|
|
849
902
|
### Alignment of `pending` value in `useAsyncData` and `useFetch`
|
|
850
903
|
|
|
851
904
|
🚦 **Impact Level**: Medium
|
|
@@ -782,11 +782,16 @@ export default defineNuxtConfig({
|
|
|
782
782
|
useAsyncData: {
|
|
783
783
|
deep: true,
|
|
784
784
|
},
|
|
785
|
+
useState: {
|
|
786
|
+
resetOnClear: true,
|
|
787
|
+
},
|
|
785
788
|
},
|
|
786
789
|
},
|
|
787
790
|
})
|
|
788
791
|
```
|
|
789
792
|
|
|
793
|
+
The `useState.resetOnClear` option controls whether [`clearNuxtState`](/docs/4.x/api/utils/clear-nuxt-state) resets state to its initial value (provided by the `init` function of [`useState`](/docs/4.x/api/composables/use-state)) instead of setting it to `undefined`. This defaults to `true` with `compatibilityVersion: 5`.
|
|
794
|
+
|
|
790
795
|
## purgeCachedData
|
|
791
796
|
|
|
792
797
|
Whether to clean up Nuxt static and asyncData caches on route navigation.
|
|
@@ -52,3 +52,7 @@ To achieve full customization, you can implement your own one based on [its sour
|
|
|
52
52
|
::callout
|
|
53
53
|
You can hook into the underlying announcer instance using [the `useRouteAnnouncer` composable](/docs/4.x/api/composables/use-route-announcer), which allows you to set a custom announcement message.
|
|
54
54
|
::
|
|
55
|
+
|
|
56
|
+
::callout
|
|
57
|
+
For announcing in-page content changes (form validation, toast notifications, loading states, etc.), use the [`<NuxtAnnouncer>`](/docs/4.x/api/components/nuxt-announcer) component with the [`useAnnouncer`](/docs/4.x/api/composables/use-announcer) composable instead.
|
|
58
|
+
::
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: '<NuxtAnnouncer>'
|
|
3
|
+
description: 'The <NuxtAnnouncer> component adds a hidden element to announce dynamic content changes to assistive technologies.'
|
|
4
|
+
links:
|
|
5
|
+
- label: Source
|
|
6
|
+
icon: i-simple-icons-github
|
|
7
|
+
to: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/components/nuxt-announcer.ts
|
|
8
|
+
size: xs
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
::important
|
|
12
|
+
This component is available in Nuxt v3.17+.
|
|
13
|
+
::
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
Add `<NuxtAnnouncer/>` in your [`app.vue`](/docs/4.x/directory-structure/app/app) or [`app/layouts/`](/docs/4.x/directory-structure/app/layouts) to enable announcing dynamic content changes to screen readers. This is useful for form validation, toast notifications, loading states, and other in-page updates.
|
|
18
|
+
|
|
19
|
+
```vue [app/app.vue]
|
|
20
|
+
<template>
|
|
21
|
+
<NuxtAnnouncer />
|
|
22
|
+
<NuxtRouteAnnouncer />
|
|
23
|
+
<NuxtLayout>
|
|
24
|
+
<NuxtPage />
|
|
25
|
+
</NuxtLayout>
|
|
26
|
+
</template>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then use the [`useAnnouncer`](/docs/4.x/api/composables/use-announcer) composable anywhere in your app to announce messages:
|
|
30
|
+
|
|
31
|
+
```vue [app/pages/contact.vue]
|
|
32
|
+
<script setup lang="ts">
|
|
33
|
+
const { polite, assertive } = useAnnouncer()
|
|
34
|
+
|
|
35
|
+
async function submitForm () {
|
|
36
|
+
try {
|
|
37
|
+
await $fetch('/api/contact', { method: 'POST', body: formData })
|
|
38
|
+
polite('Message sent successfully')
|
|
39
|
+
} catch (error) {
|
|
40
|
+
assertive('Error: Failed to send message')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Slots
|
|
47
|
+
|
|
48
|
+
You can pass custom HTML or components through the announcer's default slot.
|
|
49
|
+
|
|
50
|
+
```vue
|
|
51
|
+
<template>
|
|
52
|
+
<NuxtAnnouncer>
|
|
53
|
+
<template #default="{ message }">
|
|
54
|
+
<p>{{ message }}</p>
|
|
55
|
+
</template>
|
|
56
|
+
</NuxtAnnouncer>
|
|
57
|
+
</template>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Props
|
|
61
|
+
|
|
62
|
+
- `atomic`: Controls if screen readers announce only changes or the entire content. Set to true for full content readouts on updates, false for changes only. (default `true`)
|
|
63
|
+
- `politeness`: Sets the default urgency for screen reader announcements: `off` (disable the announcement), `polite` (waits for silence), or `assertive` (interrupts immediately). (default `polite`)
|
|
64
|
+
|
|
65
|
+
## Differences from `<NuxtRouteAnnouncer>`
|
|
66
|
+
|
|
67
|
+
| Aspect | `<NuxtRouteAnnouncer>` | `<NuxtAnnouncer>` |
|
|
68
|
+
|--------|------------------------|-------------------|
|
|
69
|
+
| **Purpose** | Announces route/page changes | Announces any dynamic content |
|
|
70
|
+
| **Trigger** | Automatic on navigation | Manual via `polite()`/`assertive()` |
|
|
71
|
+
| **Message source** | Page `<title>` | Developer-provided |
|
|
72
|
+
| **atomic default** | `false` | `true` |
|
|
73
|
+
|
|
74
|
+
::callout
|
|
75
|
+
This component is optional. :br
|
|
76
|
+
To achieve full customization, you can implement your own one based on [its source code](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/components/nuxt-announcer.ts).
|
|
77
|
+
::
|
|
78
|
+
|
|
79
|
+
::callout
|
|
80
|
+
You can hook into the underlying announcer instance using [the `useAnnouncer` composable](/docs/4.x/api/composables/use-announcer), which allows you to set custom announcement messages.
|
|
81
|
+
::
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'useAnnouncer'
|
|
3
|
+
description: A composable for announcing messages to screen readers.
|
|
4
|
+
links:
|
|
5
|
+
- label: Source
|
|
6
|
+
icon: i-simple-icons-github
|
|
7
|
+
to: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/announcer.ts
|
|
8
|
+
size: xs
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
::important
|
|
12
|
+
This composable is available in Nuxt v3.17+.
|
|
13
|
+
::
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
A composable for announcing dynamic content changes to screen readers. Unlike [`useRouteAnnouncer`](/docs/api/composables/use-route-announcer) which automatically announces route changes, `useAnnouncer` gives you manual control over what and when to announce.
|
|
18
|
+
|
|
19
|
+
Use this for in-page updates like form validation, async operations, toast notifications, and live content changes.
|
|
20
|
+
|
|
21
|
+
## Parameters
|
|
22
|
+
|
|
23
|
+
- `politeness`: Sets the default urgency for screen reader announcements: `off` (disable the announcement), `polite` (waits for silence), or `assertive` (interrupts immediately). (default `polite`)
|
|
24
|
+
|
|
25
|
+
## Properties
|
|
26
|
+
|
|
27
|
+
### `message`
|
|
28
|
+
|
|
29
|
+
- **type**: `Ref<string>`
|
|
30
|
+
- **description**: The current message to announce
|
|
31
|
+
|
|
32
|
+
### `politeness`
|
|
33
|
+
|
|
34
|
+
- **type**: `Ref<'polite' | 'assertive' | 'off'>`
|
|
35
|
+
- **description**: Screen reader announcement urgency level
|
|
36
|
+
|
|
37
|
+
## Methods
|
|
38
|
+
|
|
39
|
+
### `set(message, politeness = "polite")`
|
|
40
|
+
|
|
41
|
+
Sets the message to announce with its urgency level.
|
|
42
|
+
|
|
43
|
+
### `polite(message)`
|
|
44
|
+
|
|
45
|
+
Sets the message with `politeness = "polite"`. Use for non-urgent updates that can wait for the screen reader to finish its current task.
|
|
46
|
+
|
|
47
|
+
### `assertive(message)`
|
|
48
|
+
|
|
49
|
+
Sets the message with `politeness = "assertive"`. Use for urgent updates that should interrupt the screen reader immediately.
|
|
50
|
+
|
|
51
|
+
## Example
|
|
52
|
+
|
|
53
|
+
```vue [app/pages/contact.vue]
|
|
54
|
+
<script setup lang="ts">
|
|
55
|
+
const { polite, assertive } = useAnnouncer()
|
|
56
|
+
|
|
57
|
+
async function submitForm () {
|
|
58
|
+
try {
|
|
59
|
+
await $fetch('/api/contact', { method: 'POST', body: formData })
|
|
60
|
+
polite('Message sent successfully')
|
|
61
|
+
} catch (error) {
|
|
62
|
+
assertive('Error: Failed to send message')
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Use Cases
|
|
69
|
+
|
|
70
|
+
### Form Validation
|
|
71
|
+
|
|
72
|
+
```vue [app/components/LoginForm.vue]
|
|
73
|
+
<script setup lang="ts">
|
|
74
|
+
const { assertive } = useAnnouncer()
|
|
75
|
+
|
|
76
|
+
function validateForm () {
|
|
77
|
+
const errors = []
|
|
78
|
+
if (!email.value) { errors.push('Email is required') }
|
|
79
|
+
if (!password.value) { errors.push('Password is required') }
|
|
80
|
+
|
|
81
|
+
if (errors.length) {
|
|
82
|
+
assertive(`Form has ${errors.length} errors: ${errors.join(', ')}`)
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
return true
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Loading States
|
|
91
|
+
|
|
92
|
+
```vue [app/pages/dashboard.vue]
|
|
93
|
+
<script setup lang="ts">
|
|
94
|
+
const { polite } = useAnnouncer()
|
|
95
|
+
|
|
96
|
+
const { data, status } = await useFetch('/api/data')
|
|
97
|
+
|
|
98
|
+
watch(status, (newStatus) => {
|
|
99
|
+
if (newStatus === 'pending') {
|
|
100
|
+
polite('Loading data...')
|
|
101
|
+
} else if (newStatus === 'success') {
|
|
102
|
+
polite('Data loaded successfully')
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
</script>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Search Results
|
|
109
|
+
|
|
110
|
+
```vue [app/components/Search.vue]
|
|
111
|
+
<script setup lang="ts">
|
|
112
|
+
const { polite } = useAnnouncer()
|
|
113
|
+
|
|
114
|
+
const results = ref([])
|
|
115
|
+
|
|
116
|
+
watch(results, (newResults) => {
|
|
117
|
+
polite(`Found ${newResults.length} results`)
|
|
118
|
+
})
|
|
119
|
+
</script>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
::callout
|
|
123
|
+
You need to add the [`<NuxtAnnouncer>`](/docs/4.x/api/components/nuxt-announcer) component to your app for the announcements to be rendered in the DOM.
|
|
124
|
+
::
|
|
125
|
+
|
|
126
|
+
::callout
|
|
127
|
+
For automatic announcements of route/page changes, use [`useRouteAnnouncer`](/docs/4.x/api/composables/use-route-announcer) with the [`<NuxtRouteAnnouncer>`](/docs/4.x/api/components/nuxt-route-announcer) component instead.
|
|
128
|
+
::
|
|
@@ -56,3 +56,7 @@ const { message, politeness, set, polite, assertive } = useRouteAnnouncer({
|
|
|
56
56
|
})
|
|
57
57
|
</script>
|
|
58
58
|
```
|
|
59
|
+
|
|
60
|
+
::callout
|
|
61
|
+
For announcing dynamic in-page content changes (form validation, toasts, loading states), use [`useAnnouncer`](/docs/4.x/api/composables/use-announcer) instead.
|
|
62
|
+
::
|
|
@@ -9,15 +9,17 @@ links:
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
::note
|
|
12
|
-
This method is useful if you want to invalidate the state of `useState`.
|
|
12
|
+
This method is useful if you want to invalidate the state of `useState`. You can also reset the state to its initial value by passing `{ reset: true }` as the second parameter.
|
|
13
13
|
::
|
|
14
14
|
|
|
15
15
|
## Type
|
|
16
16
|
|
|
17
17
|
```ts [Signature]
|
|
18
|
-
export function clearNuxtState (keys?: string | string[] | ((key: string) => boolean)): void
|
|
18
|
+
export function clearNuxtState (keys?: string | string[] | ((key: string) => boolean), opts?: ClearNuxtStateOptions): void
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Parameters
|
|
22
22
|
|
|
23
23
|
- `keys`: One or an array of keys that are used in [`useState`](/docs/4.x/api/composables/use-state) to delete their cached state. If no keys are provided, **all state** will be invalidated.
|
|
24
|
+
- `opts`: An options object to configure the clear behavior.
|
|
25
|
+
- `reset`: When set to `true`, resets the state to the initial value provided by the `init` function of [`useState`](/docs/4.x/api/composables/use-state) instead of setting it to `undefined`. When not specified, defaults to the value of `experimental.defaults.useState.resetOnClear` in your Nuxt config (which is `true` with `compatibilityVersion: 5`).
|