@nuxt/docs-nightly 4.3.1-29507030.8e4f35f8 → 4.3.1-29507514.0ed26bbf
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.
|
@@ -200,6 +200,96 @@ It is highly recommended to prefix your exports to avoid conflicts with user cod
|
|
|
200
200
|
Note that all components, pages, composables and other files that would be normally placed in your `app/` folder need to be in `runtime/app/`. This will mean they can be type checked properly.
|
|
201
201
|
::
|
|
202
202
|
|
|
203
|
+
### Add Keyed Functions
|
|
204
|
+
|
|
205
|
+
Sometimes, you may need to maintain state consistency between the server and the client. Examples include Nuxt's built-in `useState` or `useAsyncData` composables. Nuxt provides a way to register such functions for automatic key injection.
|
|
206
|
+
|
|
207
|
+
When a function is registered, Nuxt’s compiler automatically injects a unique key as an additional argument if the function is called with fewer than the specified number of arguments. This key remains stable between server-side rendering and client hydration.
|
|
208
|
+
|
|
209
|
+
::tip
|
|
210
|
+
The injected key is a hash derived from the file path and call location.
|
|
211
|
+
::
|
|
212
|
+
|
|
213
|
+
Use the `keyedComposables` option to register your function:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
import { createResolver, defineNuxtModule } from '@nuxt/kit'
|
|
217
|
+
|
|
218
|
+
export default defineNuxtModule({
|
|
219
|
+
setup (options, nuxt) {
|
|
220
|
+
const resolver = createResolver(import.meta.url)
|
|
221
|
+
|
|
222
|
+
nuxt.options.optimization.keyedComposables.push({
|
|
223
|
+
name: 'useMyState',
|
|
224
|
+
source: resolver.resolve('./runtime/composables/state'),
|
|
225
|
+
argumentLength: 2,
|
|
226
|
+
})
|
|
227
|
+
},
|
|
228
|
+
})
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The `keyedComposables` configuration accepts an array of objects with the following properties:
|
|
232
|
+
|
|
233
|
+
| Property | Type | Description |
|
|
234
|
+
|------------------|----------|----------------------------------------------------------------------------------------------------------------------------|
|
|
235
|
+
| `name` | `string` | The function name. Use `'default'` for default exports (the callable name will be derived from the filename in camelCase). |
|
|
236
|
+
| `source` | `string` | Resolved path to the file where the function is defined. Supports Nuxt aliases (`~`, `@`, etc.) |
|
|
237
|
+
| `argumentLength` | `number` | Maximum number of arguments the function accepts. When called with fewer arguments, a unique key is injected. |
|
|
238
|
+
|
|
239
|
+
For example, with `argumentLength: 2`:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
useMyState() // useMyState('$HJiaryoL2y')
|
|
243
|
+
useMyState('myKey') // useMyState('myKey', '$HJiaryoL2y')
|
|
244
|
+
useMyState('a', 'b') // not transformed (already has 2 arguments)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
::warning
|
|
248
|
+
The key injection plugin verifies the exact resolved import source of each function call. It does not follow barrel exports. The function must be exported from the exact source file specified in the `source` property.
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
// ✅ Works - direct import matches the configured source
|
|
252
|
+
import { useMyState } from 'my-module/runtime/composables/state'
|
|
253
|
+
|
|
254
|
+
// ❌ Won't work - re-exported through a barrel file
|
|
255
|
+
import { useMyState } from 'my-module/runtime/composables' // index.ts barrel
|
|
256
|
+
```
|
|
257
|
+
::
|
|
258
|
+
|
|
259
|
+
::warning
|
|
260
|
+
The function call must be statically analyzable. The compiler cannot inject keys for dynamic or indirect function calls.
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
import { useMyState } from 'my-module/runtime/composables/state'
|
|
264
|
+
import * as composables from 'my-module/runtime/composables/state'
|
|
265
|
+
|
|
266
|
+
// ✅ Works - direct function call
|
|
267
|
+
useMyState()
|
|
268
|
+
|
|
269
|
+
// ✅ Works - called on namespace import
|
|
270
|
+
composables.useMyState()
|
|
271
|
+
|
|
272
|
+
// ❌ Won't work - dynamic property access
|
|
273
|
+
const name = 'useMyState'
|
|
274
|
+
composables[name]()
|
|
275
|
+
|
|
276
|
+
// ❌ Won't work - reassigned to a variable
|
|
277
|
+
const myFn = useMyState
|
|
278
|
+
myFn()
|
|
279
|
+
|
|
280
|
+
// ❌ Won't work - passed as a callback
|
|
281
|
+
someFunction(useMyState)
|
|
282
|
+
|
|
283
|
+
// ❌ Won't work - destructured with renaming in a nested scope
|
|
284
|
+
function setup () {
|
|
285
|
+
const { useMyState: localState } = composables
|
|
286
|
+
localState() // not transformed
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ...
|
|
290
|
+
```
|
|
291
|
+
::
|
|
292
|
+
|
|
203
293
|
## Add Server Routes
|
|
204
294
|
|
|
205
295
|
```ts
|
package/4.api/6.nuxt-config.md
CHANGED
|
@@ -1014,8 +1014,12 @@ Options passed directly to the transformer from `unctx` that preserves async con
|
|
|
1014
1014
|
|
|
1015
1015
|
Functions to inject a key for.
|
|
1016
1016
|
|
|
1017
|
-
As long as the number of arguments passed to the function is less than `argumentLength`, an additional magic string will be injected
|
|
1018
|
-
The key
|
|
1017
|
+
As long as the number of arguments passed to the function is less than `argumentLength`, an additional magic string will be injected as the last argument. This key is stable between SSR and client-side hydration. You will need to take steps to handle this additional key.
|
|
1018
|
+
The key is unique based on the location of the function being invoked within the file.
|
|
1019
|
+
|
|
1020
|
+
::read-more{to="/docs/4.x/guide/modules/recipes-basics#add-keyed-functions"}
|
|
1021
|
+
Learn more about keyed functions.
|
|
1022
|
+
::
|
|
1019
1023
|
|
|
1020
1024
|
- **Type**: `array`
|
|
1021
1025
|
- **Default**
|
|
@@ -1023,31 +1027,38 @@ The key will be unique based on the location of the function being invoked withi
|
|
|
1023
1027
|
[
|
|
1024
1028
|
{
|
|
1025
1029
|
"name": "callOnce",
|
|
1026
|
-
"argumentLength": 3
|
|
1030
|
+
"argumentLength": 3,
|
|
1031
|
+
"source": "#app/composables/once"
|
|
1027
1032
|
},
|
|
1028
1033
|
{
|
|
1029
1034
|
"name": "defineNuxtComponent",
|
|
1030
|
-
"argumentLength": 2
|
|
1035
|
+
"argumentLength": 2,
|
|
1036
|
+
"source": "#app/composables/component"
|
|
1031
1037
|
},
|
|
1032
1038
|
{
|
|
1033
1039
|
"name": "useState",
|
|
1034
|
-
"argumentLength": 2
|
|
1040
|
+
"argumentLength": 2,
|
|
1041
|
+
"source": "#app/composables/state"
|
|
1035
1042
|
},
|
|
1036
1043
|
{
|
|
1037
1044
|
"name": "useFetch",
|
|
1038
|
-
"argumentLength": 3
|
|
1045
|
+
"argumentLength": 3,
|
|
1046
|
+
"source": "#app/composables/fetch"
|
|
1039
1047
|
},
|
|
1040
1048
|
{
|
|
1041
1049
|
"name": "useAsyncData",
|
|
1042
|
-
"argumentLength": 3
|
|
1050
|
+
"argumentLength": 3,
|
|
1051
|
+
"source": "#app/composables/asyncData"
|
|
1043
1052
|
},
|
|
1044
1053
|
{
|
|
1045
1054
|
"name": "useLazyAsyncData",
|
|
1046
|
-
"argumentLength": 3
|
|
1055
|
+
"argumentLength": 3,
|
|
1056
|
+
"source": "#app/composables/asyncData"
|
|
1047
1057
|
},
|
|
1048
1058
|
{
|
|
1049
1059
|
"name": "useLazyFetch",
|
|
1050
|
-
"argumentLength": 3
|
|
1060
|
+
"argumentLength": 3,
|
|
1061
|
+
"source": "#app/composables/fetch"
|
|
1051
1062
|
}
|
|
1052
1063
|
]
|
|
1053
1064
|
```
|