Skip to content

Commit 1931877

Browse files
authored
Remove prefetch from instant config (vercel#92761)
prefetching is now controlled with the prefetch export and this option is inert on the instant export. this removes the prefetch option as a valid property on the instant config type. also updates the ts plugin for this export and adds the definition for the previously landed prefetch export
1 parent 3e847df commit 1931877

222 files changed

Lines changed: 499 additions & 811 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/next/src/build/segment-config/app/app-segment-config.ts

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ const RuntimeSampleSchema = z
1919
})
2020
.strict()
2121

22-
const InstantConfigStaticSchema = z
22+
const InstantConfigObjectSchema = z
2323
.object({
24-
prefetch: z.literal('static'),
2524
samples: z.array(RuntimeSampleSchema).min(1).optional(),
2625
from: z.array(z.string()).optional(),
2726
unstable_disableValidation: z.literal(true).optional(),
@@ -30,22 +29,9 @@ const InstantConfigStaticSchema = z
3029
})
3130
.strict()
3231

33-
const InstantConfigRuntimeSchema = z
34-
.object({
35-
prefetch: z.literal('runtime'),
36-
samples: z.array(RuntimeSampleSchema).min(1),
37-
from: z.array(z.string()).optional(),
38-
unstable_disableValidation: z.literal(true).optional(),
39-
unstable_disableDevValidation: z.literal(true).optional(),
40-
unstable_disableBuildValidation: z.literal(true).optional(),
41-
})
42-
.strict()
43-
4432
const InstantConfigSchema = z.union([
45-
z.discriminatedUnion('prefetch', [
46-
InstantConfigStaticSchema,
47-
InstantConfigRuntimeSchema,
48-
]),
33+
InstantConfigObjectSchema,
34+
z.literal(true),
4935
z.literal(false),
5036
])
5137

@@ -56,7 +42,7 @@ const PrefetchSchema = z.enum([
5642
'force-runtime',
5743
])
5844

59-
export type Instant = InstantConfigStatic | InstantConfigRuntime | false
45+
export type Instant = InstantConfig | true | false
6046

6147
export type Prefetch =
6248
| 'auto'
@@ -65,46 +51,35 @@ export type Prefetch =
6551
| 'force-runtime'
6652

6753
export type InstantConfigForTypeCheckInternal = __GenericInstantConfig | Instant
68-
// the __GenericPrefetch type is used to avoid type widening issues with
54+
// the __GenericInstantConfig type is used to avoid type widening issues with
6955
// our choice to make exports the medium for programming a Next.js application
7056
// With exports the type is controlled by the module and all we can do is assert on it
7157
// from a consumer. However with string literals in objects these are by default typed widely
7258
// and thus cannot match the discriminated union type. If we figure out a better way we should
73-
// delete the __GenericPrefetch member.
59+
// delete the __GenericInstantConfig member.
7460
interface __GenericInstantConfig {
75-
prefetch: string
7661
samples?: Array<WideInstantSample>
7762
from?: string[]
7863
unstable_disableValidation?: boolean
7964
unstable_disableDevValidation?: boolean
8065
unstable_disableBuildValidation?: boolean
8166
}
8267

83-
interface InstantConfigStatic {
84-
prefetch: 'static'
85-
samples?: Array<InstantSample>
86-
from?: string[]
87-
unstable_disableValidation?: true
88-
unstable_disableDevValidation?: true
89-
unstable_disableBuildValidation?: true
68+
type WideInstantSample = {
69+
cookies?: InstantSample['cookies']
70+
headers?: Array<string[]>
71+
params?: InstantSample['params']
72+
searchParams?: InstantSample['searchParams']
9073
}
9174

92-
interface InstantConfigRuntime {
93-
prefetch: 'runtime'
94-
samples: Array<InstantSample>
75+
export interface InstantConfig {
76+
samples?: Array<InstantSample>
9577
from?: string[]
9678
unstable_disableValidation?: true
9779
unstable_disableDevValidation?: true
9880
unstable_disableBuildValidation?: true
9981
}
10082

101-
type WideInstantSample = {
102-
cookies?: InstantSample['cookies']
103-
headers?: Array<string[]>
104-
params?: InstantSample['params']
105-
searchParams?: InstantSample['searchParams']
106-
}
107-
10883
export type InstantSample = {
10984
cookies?: Array<{
11085
name: string
@@ -212,7 +187,7 @@ export function parseAppSegmentConfig(
212187
case 'unstable_instant': {
213188
return {
214189
// @TODO replace this link with a link to the docs when they are written
215-
message: `Invalid unstable_instant value ${JSON.stringify(ctx.data)} on "${route}", must be an object with \`prefetch: "static"\` or \`prefetch: "runtime"\`, or \`false\`. Read more at https://nextjs.org/docs/messages/invalid-instant-configuration`,
190+
message: `Invalid unstable_instant value ${JSON.stringify(ctx.data)} on "${route}", must be \`true\`, \`false\`, or an object. Read more at https://nextjs.org/docs/messages/invalid-instant-configuration`,
216191
}
217192
}
218193
case 'unstable_prefetch': {

packages/next/src/server/app-render/create-flight-router-state-from-loader-tree.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ async function createFlightRouterStateFromLoaderTreeImpl(
8888
prefetchHints |= PrefetchHint.IsRootLayout
8989
}
9090

91-
if (instantConfig && typeof instantConfig === 'object') {
91+
if (
92+
instantConfig === true ||
93+
(typeof instantConfig === 'object' && instantConfig !== null)
94+
) {
9295
prefetchHints |= PrefetchHint.SubtreeHasInstant
9396
}
9497

packages/next/src/server/app-render/instant-validation/instant-config.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ export async function isPageAllowedToBlock(tree: LoaderTree): Promise<boolean> {
4949
// instant UI, so we should make sure that a static shell exists.
5050
// (even if it'd use runtime prefetching for client navs)
5151
if (instantConfig !== undefined) {
52-
if (typeof instantConfig === 'object') {
53-
return false
54-
} else if (instantConfig === false) {
52+
if (instantConfig === false) {
5553
return true
54+
} else {
55+
return false
5656
}
5757
}
5858

@@ -84,12 +84,14 @@ async function anySegmentNeedsInstantValidation(
8484
): Promise<boolean> {
8585
const segments = await findSegmentsWithInstantConfig(rootTree)
8686

87-
// Check if there's any configs with `prefetch: 'static'` or `mode: 'instant'`.
87+
// Check if there's any non-false configs that need validation.
8888
// (If there's only `false`, there's no need to run validation).
8989
// If any segment has `unstable_disableValidation`, we skip validation for the whole tree.
9090
let needsValidation = false
9191
for (const { config } of segments) {
92-
if (typeof config === 'object') {
92+
if (config === true) {
93+
needsValidation = true
94+
} else if (typeof config === 'object') {
9395
if (
9496
config.unstable_disableValidation === true ||
9597
(mode === 'dev' && config.unstable_disableDevValidation === true) ||

packages/next/src/server/app-render/instant-validation/instant-validation.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,10 @@ export async function createCombinedPayloadAtDepth(
11551155
(layoutOrPageMod as AppSegmentConfig).unstable_instant ?? null
11561156
prefetchConfig =
11571157
(layoutOrPageMod as AppSegmentConfig).unstable_prefetch ?? null
1158-
if (instantConfig && typeof instantConfig === 'object') {
1158+
if (
1159+
instantConfig === true ||
1160+
(typeof instantConfig === 'object' && instantConfig !== null)
1161+
) {
11591162
const rawFactory: unknown = (layoutOrPageMod as any)
11601163
.__debugCreateInstantConfigStack
11611164
localCreateInstantStack =
@@ -1243,7 +1246,10 @@ export async function createCombinedPayloadAtDepth(
12431246
requiresInstantUI = false
12441247
createInstantStack = null
12451248
configDepth = -1
1246-
} else if (instantConfig && typeof instantConfig === 'object') {
1249+
} else if (
1250+
instantConfig === true ||
1251+
(typeof instantConfig === 'object' && instantConfig !== null)
1252+
) {
12471253
requiresInstantUI = true
12481254
createInstantStack = localCreateInstantStack
12491255
configDepth = segmentDepth

packages/next/src/server/typescript/rules/config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,14 @@ const API_DOCS: Record<
147147
link: 'https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#maxduration',
148148
},
149149
unstable_instant: {
150-
description: `Specifies the default prefetching behavior for this segment. This configuration is currently under development and will change.`,
150+
description: `Enables instant navigation validation for this segment. This configuration is currently under development and will change.`,
151151
link: '(docs coming soon)',
152-
type: 'object | false',
152+
type: 'true | object | false',
153153
// TODO: ideally, we'd validate the config object somehow, but this is difficult to do
154154
// with the way this plugin is currently structured.
155155
// For now, since we don't provide an `options` here, we won't do any validation in
156156
// `getSemanticDiagnosticsForExportVariableStatement` below, and only provide hover a tooltip + autocomplete.
157-
insertText: 'unstable_instant = { prefetch: "static" };',
157+
insertText: 'unstable_instant = true;',
158158
},
159159
unstable_prefetch: {
160160
description: `Controls prefetching behavior for this segment. This configuration is currently under development and will change.`,

test/development/app-dir/cache-components-dev-warmup/fixtures/with-prefetch-config/app/apis/[param]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CachedData } from '../../data-fetching'
33
import { connection } from 'next/server'
44
import { Suspense } from 'react'
55

6-
export const unstable_instant = { prefetch: 'runtime', samples: [{}] }
6+
export const unstable_instant = true
77
export const unstable_prefetch = 'force-runtime'
88

99
const CACHE_KEY = __dirname + '/__PAGE__'

test/development/app-dir/cache-components-dev-warmup/fixtures/with-prefetch-config/app/private-cache/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Suspense } from 'react'
22
import { UncachedFetch, CachedData } from '../data-fetching'
33
import { PrivateCachedData } from './data-fetching'
44

5-
export const unstable_instant = { prefetch: 'runtime', samples: [{}] }
5+
export const unstable_instant = true
66
export const unstable_prefetch = 'force-runtime'
77

88
const CACHE_KEY = '/private-cache/__LAYOUT__'

test/development/app-dir/cache-components-dev-warmup/fixtures/with-prefetch-config/app/short-lived-cache/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Suspense } from 'react'
22
import { UncachedFetch, CachedData } from '../data-fetching'
33
import { ShortLivedCache } from './data-fetching'
44

5-
export const unstable_instant = { prefetch: 'runtime', samples: [{}] }
5+
export const unstable_instant = true
66
export const unstable_prefetch = 'force-runtime'
77

88
const CACHE_KEY = __dirname + '/__LAYOUT__'

test/development/app-dir/cache-components-dev-warmup/fixtures/with-prefetch-config/app/simple/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Suspense } from 'react'
22
import { UncachedFetch, CachedFetch, CachedData } from '../data-fetching'
33

4-
export const unstable_instant = { prefetch: 'runtime', samples: [{}] }
4+
export const unstable_instant = true
55
export const unstable_prefetch = 'force-runtime'
66

77
const CACHE_KEY = __dirname + '/__LAYOUT__'

test/development/app-dir/cache-components-dev-warmup/fixtures/with-prefetch-config/app/successive-caches/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const unstable_instant = { prefetch: 'runtime', samples: [{}] }
1+
export const unstable_instant = true
22
export const unstable_prefetch = 'force-runtime'
33

44
export default async function Page() {

0 commit comments

Comments
 (0)