Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
---
title: Invalid Prefetch Configuration
title: Invalid Instant Configuration
---

## Why This Message Occurred

You provided an invalid configuration for `export const unstable_prefetch` in a Layout or Page file.
You provided an invalid configuration for `export const unstable_instant` in a Layout or Page file.

### Example of Correct Usage

#### Static Prefetching

```tsx filename="app/.../layout.tsx"
export const unstable_prefetch = {
mode: 'static',
export const unstable_instant = {
prefetch: 'static',
}
```

#### Runtime Prefetching

```tsx filename="app/[slug]/page.tsx"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [
{
cookies: [{ name: 'experiment', value: 'A' }],
Expand Down
24 changes: 12 additions & 12 deletions errors/next-prerender-runtime-crypto.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ If you are generating a token to talk to a database that itself should be cached
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -40,8 +40,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -65,8 +65,8 @@ If you require this random value to be unique per Request and an async version o
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -84,8 +84,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -107,8 +107,8 @@ If you require this random value to be unique per Request and an async version o
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -122,8 +122,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down
32 changes: 16 additions & 16 deletions errors/next-prerender-runtime-current-time.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ If you are using the current time for performance tracking with elapsed time use
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -42,8 +42,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -67,8 +67,8 @@ If you want to read the time when some cache entry is created (such as when a Ne
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down Expand Up @@ -96,8 +96,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down Expand Up @@ -136,8 +136,8 @@ If you go with this approach you will need to ensure the Client Component which
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down Expand Up @@ -193,8 +193,8 @@ export function RelativeTime({ when }) {
```

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down Expand Up @@ -230,8 +230,8 @@ Next.js enforces that it can always produce at least a partially static initial
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -249,8 +249,8 @@ export default async function Page() {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down
16 changes: 8 additions & 8 deletions errors/next-prerender-runtime-random.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ If your random value is cacheable, move the `Math.random()` call to a `"use cach
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -40,8 +40,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -68,8 +68,8 @@ If you want the random value to be evaluated on each Request precede it with `aw
Before:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand All @@ -85,8 +85,8 @@ export default async function Page({ params }) {
After:

```jsx filename="app/page.js"
export const unstable_prefetch = {
mode: 'runtime',
export const unstable_instant = {
prefetch: 'runtime',
samples: [...],
}

Expand Down
3 changes: 2 additions & 1 deletion packages/next/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -987,5 +987,6 @@
"986": "Server Action arguments list is too long (%s). Maximum allowed is %s.",
"987": "Invalid \\`deploymentId\\` configuration: must be a string. See https://nextjs.org/docs/messages/deploymentid-not-a-string",
"988": "Invalid \\`deploymentId\\` configuration: contains invalid characters. Only alphanumeric characters, hyphens, and underscores are allowed. See https://nextjs.org/docs/messages/deploymentid-invalid-characters",
"989": "Loaded static props were from an outdated deployment, forcing a hard reload"
"989": "Loaded static props were from an outdated deployment, forcing a hard reload",
"990": "Page \"%s\" cannot use \\`export const unstable_instant = ...\\` without enabling \\`cacheComponents\\`."
}
4 changes: 2 additions & 2 deletions packages/next/src/build/analysis/get-page-static-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,9 +684,9 @@ export async function getAppPageStaticInfo({
)
}

if ('unstable_prefetch' in config && !nextConfig.cacheComponents) {
if ('unstable_instant' in config && !nextConfig.cacheComponents) {
throw new Error(
`Page "${page}" cannot use \`export const unstable_prefetch = ...\` without enabling \`cacheComponents\`.`
`Page "${page}" cannot use \`export const unstable_instant = ...\` without enabling \`cacheComponents\`.`
)
}

Expand Down
44 changes: 25 additions & 19 deletions packages/next/src/build/segment-config/app/app-segment-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,65 @@ const RuntimeSampleSchema = z
})
.strict()

const StaticPrefetchSchema = z
const InstantConfigStaticSchema = z
.object({
mode: z.literal('static'),
prefetch: z.literal('static'),
from: z.array(z.string()).optional(),
expectUnableToVerify: z.boolean().optional(),
})
.strict()

const RuntimePrefetchSchema = z
const InstantConfigRuntimeSchema = z
.object({
mode: z.literal('runtime'),
prefetch: z.literal('runtime'),
samples: z.array(RuntimeSampleSchema).min(1),
from: z.array(z.string()).optional(),
expectUnableToVerify: z.boolean().optional(),
})
.strict()

const PrefetchSchema = z.discriminatedUnion('mode', [
StaticPrefetchSchema,
RuntimePrefetchSchema,
const InstantConfigSchema = z.discriminatedUnion('prefetch', [
InstantConfigStaticSchema,
InstantConfigRuntimeSchema,
])

export type Prefetch = StaticPrefetch | RuntimePrefetch
export type PrefetchForTypeCheckInternal = __GenericPrefetch | Prefetch
export type InstantConfig = InstantConfigStatic | InstantConfigRuntime
export type InstantConfigForTypeCheckInternal =
| __GenericInstantConfig
| InstantConfig
// the __GenericPrefetch type is used to avoid type widening issues with
// our choice to make exports the medium for programming a Next.js application
// With exports the type is controlled by the module and all we can do is assert on it
// from a consumer. However with string literals in objects these are by default typed widely
// and thus cannot match the discriminated union type. If we figure out a better way we should
// delete the __GenericPrefetch member.
interface __GenericPrefetch {
mode: string
interface __GenericInstantConfig {
prefetch: string
samples?: Array<WideRuntimeSample>
from?: string[]
expectUnableToVerify?: boolean
}
interface StaticPrefetch {
mode: 'static'

interface InstantConfigStatic {
prefetch: 'static'
from?: string[]
expectUnableToVerify?: boolean
}
interface RuntimePrefetch {
mode: 'runtime'

interface InstantConfigRuntime {
prefetch: 'runtime'
samples: Array<RuntimeSample>
from?: string[]
expectUnableToVerify?: boolean
}

type WideRuntimeSample = {
cookies?: RuntimeSample['cookies']
headers?: Array<string[]>
params?: RuntimeSample['params']
searchParams?: RuntimeSample['searchParams']
}

type RuntimeSample = {
cookies?: Array<{
name: string
Expand Down Expand Up @@ -127,7 +133,7 @@ const AppSegmentConfigSchema = z.object({
/**
* How this segment should be prefetched.
*/
unstable_prefetch: PrefetchSchema.optional(),
unstable_instant: InstantConfigSchema.optional(),

/**
* The preferred region for the page.
Expand Down Expand Up @@ -166,10 +172,10 @@ export function parseAppSegmentConfig(
)} on "${route}", must be a non-negative number or false`,
}
}
case 'unstable_prefetch': {
case 'unstable_instant': {
return {
// @TODO replace this link with a link to the docs when they are written
message: `Invalid unstable_prefetch value ${JSON.stringify(ctx.data)} on "${route}", must be an object with a mode of "static" or "runtime". Read more at https://nextjs.org/docs/messages/invalid-prefetch-configuration`,
message: `Invalid unstable_instant value ${JSON.stringify(ctx.data)} on "${route}", must be an object with \`prefetch: "static"\` or \`prefetch: "runtime"\`. Read more at https://nextjs.org/docs/messages/invalid-instant-configuration`,
}
}
default:
Expand Down Expand Up @@ -224,7 +230,7 @@ export type AppSegmentConfig = {
/**
* How this segment should be prefetched.
*/
unstable_prefetch?: Prefetch
unstable_instant?: InstantConfig

/**
* The preferred region for the page.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ${
: `import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'`
}
import type { PrefetchForTypeCheckInternal } from 'next/dist/build/segment-config/app/app-segment-config.js'
import type { InstantConfigForTypeCheckInternal } from 'next/dist/build/segment-config/app/app-segment-config.js'
type TEntry = typeof import('${relativePath}.js')
Expand All @@ -71,7 +71,7 @@ checkFields<Diff<{
}
config?: {}
generateStaticParams?: Function
unstable_prefetch?: PrefetchForTypeCheckInternal
unstable_instant?: InstantConfigForTypeCheckInternal
revalidate?: RevalidateRange<TEntry> | false
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
dynamicParams?: boolean
Expand Down
6 changes: 3 additions & 3 deletions packages/next/src/server/app-render/create-component-tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,11 @@ async function createComponentTreeInternal(
})
: []

const prefetchConfig = layoutOrPageMod
? (layoutOrPageMod as AppSegmentConfig).unstable_prefetch
const instantConfig = layoutOrPageMod
? (layoutOrPageMod as AppSegmentConfig).unstable_instant
: undefined
/** Whether this segment should use a runtime prefetch instead of a static prefetch. */
const hasRuntimePrefetch = prefetchConfig?.mode === 'runtime'
const hasRuntimePrefetch = instantConfig?.prefetch === 'runtime'

const [Forbidden, forbiddenStyles] =
authInterrupts && forbidden
Expand Down
Loading
Loading