@nuxt/docs-nightly 4.6.0-29803612.ea5d49fb → 4.6.0-29809894.6056487a
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.
|
@@ -551,6 +551,80 @@ export default defineNuxtConfig({
|
|
|
551
551
|
})
|
|
552
552
|
```
|
|
553
553
|
|
|
554
|
+
### Typed `$fetch` Rebuilt on Generated Route Types
|
|
555
|
+
|
|
556
|
+
🚦 **Impact Level**: Medium
|
|
557
|
+
|
|
558
|
+
#### What Changed
|
|
559
|
+
|
|
560
|
+
With `compatibilityVersion: 5`, `$fetch` and `useFetch` are typed from the routes Nuxt's server
|
|
561
|
+
builder reports, rather than from nitro's `InternalApi` interface. As well as response types, a
|
|
562
|
+
`body`, `query` or `headers` the matching handler validates are now enforced on the call, a method
|
|
563
|
+
the route does not handle is rejected, and a response is typed as it arrives over the wire, so a
|
|
564
|
+
`Date` a handler returns is a `string` at the call site.
|
|
565
|
+
|
|
566
|
+
Two things follow from this:
|
|
567
|
+
|
|
568
|
+
- Routes you augmented by hand on nitro's `InternalApi` are no longer picked up. Augment
|
|
569
|
+
`ServerRoutes` from `@nuxt/schema` instead.
|
|
570
|
+
- The `params` option is no longer accepted by `$fetch` or `useFetch`. It was an alias for `query`.
|
|
571
|
+
|
|
572
|
+
#### Reasons for Change
|
|
573
|
+
|
|
574
|
+
Nitro v3 drops typed fetch, and the old implementation did not scale past about 300 routes. The new
|
|
575
|
+
generated route types cost the same to check whatever the route count, and carry enough information
|
|
576
|
+
to type the request as well as the response. `params` is dropped so the name is free for named route
|
|
577
|
+
parameters later.
|
|
578
|
+
|
|
579
|
+
#### Migration Steps
|
|
580
|
+
|
|
581
|
+
Move any `params` option to `query`:
|
|
582
|
+
|
|
583
|
+
```diff
|
|
584
|
+
const { data } = await useFetch('/api/search', {
|
|
585
|
+
- params: { q: 'nuxt' },
|
|
586
|
+
+ query: { q: 'nuxt' },
|
|
587
|
+
})
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Move any manual route augmentation from `InternalApi` to `ServerRoutes`:
|
|
591
|
+
|
|
592
|
+
```diff [shared/server-routes.d.ts]
|
|
593
|
+
- declare module 'nitropack' {
|
|
594
|
+
- interface InternalApi {
|
|
595
|
+
- '/api/hello': { get: { message: string } }
|
|
596
|
+
- }
|
|
597
|
+
- }
|
|
598
|
+
+ import type { Endpoint } from 'nuxt/app'
|
|
599
|
+
+
|
|
600
|
+
+ declare module '@nuxt/schema' {
|
|
601
|
+
+ interface ServerRoutes {
|
|
602
|
+
+ '/api/hello': {
|
|
603
|
+
+ [Endpoint]: {
|
|
604
|
+
+ GET: { response: { message: string } }
|
|
605
|
+
+ }
|
|
606
|
+
+ }
|
|
607
|
+
+ }
|
|
608
|
+
+ }
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
::note
|
|
612
|
+
While Nuxt 4 runs on nitro v2, nitro declares a global `$fetch` of its own, typed from
|
|
613
|
+
`InternalApi`. Import `$fetch` from `#build/fetch` where you want the generated route types to apply
|
|
614
|
+
to a direct call; `useFetch`, `useLazyFetch` and `useRequestFetch()` are unaffected.
|
|
615
|
+
::
|
|
616
|
+
|
|
617
|
+
::tip
|
|
618
|
+
Either typing can be selected on its own with
|
|
619
|
+
[`experimental.routeTypedFetch`](/docs/4.x/guide/going-further/experimental-features#routetypedfetch),
|
|
620
|
+
so you can adopt this before moving to Nuxt 5, or move to Nuxt 5 with `routeTypedFetch: false` and
|
|
621
|
+
adopt it separately. The option is temporary: from Nuxt 5 the generated route set is the only
|
|
622
|
+
source.
|
|
623
|
+
::
|
|
624
|
+
|
|
625
|
+
Set [`experimental.strictRouteTypes`](/docs/4.x/guide/going-further/experimental-features#strictroutetypes)
|
|
626
|
+
to reject a path no route answers.
|
|
627
|
+
|
|
554
628
|
### TypeScript `baseUrl` Is Ignored
|
|
555
629
|
|
|
556
630
|
🚦 **Impact Level**: Minimal
|
|
@@ -1050,6 +1050,101 @@ export default defineNuxtConfig({
|
|
|
1050
1050
|
})
|
|
1051
1051
|
```
|
|
1052
1052
|
|
|
1053
|
+
## routeTypedFetch
|
|
1054
|
+
|
|
1055
|
+
Type `$fetch` and `useFetch` from the routes your server builder reports, rather than from the
|
|
1056
|
+
responses nitro contributes to `ServerRoutes` through its `InternalApi` interface.
|
|
1057
|
+
|
|
1058
|
+
```ts twoslash [nuxt.config.ts]
|
|
1059
|
+
export default defineNuxtConfig({
|
|
1060
|
+
experimental: {
|
|
1061
|
+
routeTypedFetch: true,
|
|
1062
|
+
},
|
|
1063
|
+
})
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
The generated route set carries the `body`, `query` and `headers` a handler validates as well as its
|
|
1067
|
+
response, typed as it arrives over the wire, so a resolving call is typed more tightly than before:
|
|
1068
|
+
|
|
1069
|
+
- a `Date` a handler returns is a `string` at the call site
|
|
1070
|
+
- a `body` the handler validates cannot be omitted or given the wrong shape
|
|
1071
|
+
- a method the route does not answer is rejected
|
|
1072
|
+
- `params` is no longer accepted, since it was only ever an alias for `query`
|
|
1073
|
+
- a route you registered by augmenting `ServerRoutes` by hand needs rewriting, as the two
|
|
1074
|
+
descriptions of a route differ (see [the upgrade guide](/docs/4.x/getting-started/upgrade#typed-fetch-rebuilt-on-generated-route-types))
|
|
1075
|
+
|
|
1076
|
+
Because of those, it is opt-in, and `future.compatibilityVersion: 5` enables it. Setting it
|
|
1077
|
+
explicitly selects either typing whatever the compatibility version, so you can adopt it before
|
|
1078
|
+
moving to Nuxt 5, or move to Nuxt 5 with `routeTypedFetch: false` and adopt it separately.
|
|
1079
|
+
|
|
1080
|
+
::note
|
|
1081
|
+
This option exists only while both typings are supported. From Nuxt 5 the generated route set is the
|
|
1082
|
+
only source and the option is gone.
|
|
1083
|
+
::
|
|
1084
|
+
|
|
1085
|
+
::note
|
|
1086
|
+
While Nuxt 4 runs on nitro v2, nitro declares a global `$fetch` of its own, typed from
|
|
1087
|
+
`InternalApi`. Import `$fetch` from `#build/fetch` where you want the generated route types to apply
|
|
1088
|
+
to a direct call; `useFetch`, `useLazyFetch` and `useRequestFetch()` are unaffected.
|
|
1089
|
+
::
|
|
1090
|
+
|
|
1091
|
+
## strictRouteTypes
|
|
1092
|
+
|
|
1093
|
+
Reject a request to a path no server route answers. Requires
|
|
1094
|
+
[`routeTypedFetch`](#routetypedfetch), which types `$fetch` and `useFetch` from the routes your
|
|
1095
|
+
server will serve.
|
|
1096
|
+
|
|
1097
|
+
```ts twoslash [nuxt.config.ts]
|
|
1098
|
+
export default defineNuxtConfig({
|
|
1099
|
+
experimental: {
|
|
1100
|
+
routeTypedFetch: true,
|
|
1101
|
+
strictRouteTypes: true,
|
|
1102
|
+
},
|
|
1103
|
+
})
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
With `routeTypedFetch` enabled a response is typed by the handler that answers it whatever this
|
|
1107
|
+
option is set to. What the option decides is whether a path Nuxt does not recognise is an error or
|
|
1108
|
+
is simply typed as `unknown`.
|
|
1109
|
+
|
|
1110
|
+
- `false` (default) - a path Nuxt does not recognise is accepted and resolves to `unknown`, and no
|
|
1111
|
+
method is rejected. Nuxt cannot see every way a request may be answered: nitro middleware, a
|
|
1112
|
+
[`routeRules`](/docs/4.x/guide/concepts/rendering#hybrid-rendering) proxy or a catch-all handler
|
|
1113
|
+
can answer a path no route describes.
|
|
1114
|
+
- `true` - only the routes your server builder reports are accepted, for the methods they answer.
|
|
1115
|
+
- `'isomorphic'` - as `true`, and your pages are included as `GET` routes returning `string`, so
|
|
1116
|
+
`$fetch('/about')` is typed by the route the Vue router serves rather than rejected.
|
|
1117
|
+
|
|
1118
|
+
With the option on, a typo and a method the route does not answer are both errors:
|
|
1119
|
+
|
|
1120
|
+
```ts
|
|
1121
|
+
// server/api/todos.post.ts answers POST only
|
|
1122
|
+
await $fetch('/api/todos', { method: 'POST' })
|
|
1123
|
+
await $fetch('/api/todo', { method: 'POST' })
|
|
1124
|
+
// ^ no POST route matches '/api/todo'
|
|
1125
|
+
await $fetch('/api/todos')
|
|
1126
|
+
// ^ no GET route matches '/api/todos'
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
Two things stay accepted, because they are not Nuxt's to describe: an absolute URL
|
|
1130
|
+
(`$fetch('https://example.com')`), and a path built at runtime, which resolves to `unknown` as it
|
|
1131
|
+
does with the option off. A `baseURL` is resolved into the path before it is matched, so a request
|
|
1132
|
+
made through one is checked against the route it actually asks for. Naming the response type also
|
|
1133
|
+
opts a call out, since doing so turns off inference for the request:
|
|
1134
|
+
|
|
1135
|
+
```ts
|
|
1136
|
+
const data = await $fetch<{ id: string }>(`/api/${resource}`)
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
::note
|
|
1140
|
+
Files in your `public/` directory are not routes your server builder reports, so requesting one
|
|
1141
|
+
with `strictRouteTypes` enabled is an error. Fetch those with an explicit response type, or leave
|
|
1142
|
+
the option off.
|
|
1143
|
+
::
|
|
1144
|
+
|
|
1145
|
+
Set this only where your routing is enumerable. An app with a catch-all page under `'isomorphic'`
|
|
1146
|
+
matches every path, which is correct but means the option constrains nothing.
|
|
1147
|
+
|
|
1053
1148
|
## pendingWhenIdle
|
|
1054
1149
|
|
|
1055
1150
|
`pendingWhenIdle` controls the `pending` ref returned by `useAsyncData` and `useFetch`.
|
|
@@ -57,6 +57,7 @@ Check the [schema source code](https://github.com/nuxt/nuxt/blob/main/packages/s
|
|
|
57
57
|
| `pages:extend` | `pages` | Called after page routes are scanned from the file system. |
|
|
58
58
|
| `pages:resolved` | `pages` | Called after page routes have been augmented with scanned metadata. |
|
|
59
59
|
| `pages:routerOptions` | `{ files: Array<{ path: string, optional?: boolean }> }` | Called when resolving `router.options` files. Later items in the array override earlier ones. |
|
|
60
|
+
| `server:routes` | `routes`, `context` | Called when Nuxt needs the full set of route handlers the server will serve, so that it can type `$fetch` and `useFetch` against them. |
|
|
60
61
|
| `server:devHandler` | `handler` | Called when the dev middleware is being registered on the Nitro dev server. |
|
|
61
62
|
| `imports:sources` | `presets` | Called at setup allowing modules to extend sources. |
|
|
62
63
|
| `imports:extend` | `imports` | Called at setup allowing modules to extend imports. |
|