diff --git a/crates/next-custom-transforms/src/transforms/react_server_components.rs b/crates/next-custom-transforms/src/transforms/react_server_components.rs index 98306014b48cc..8c03305cfdd34 100644 --- a/crates/next-custom-transforms/src/transforms/react_server_components.rs +++ b/crates/next-custom-transforms/src/transforms/react_server_components.rs @@ -645,7 +645,7 @@ impl ReactServerComponentValidator { ], invalid_client_lib_apis_mapping: FxHashMap::from_iter([ - ("next/server", vec!["after", "unstable_rootParams"]), + ("next/server", vec!["after"]), ( "next/cache", vec![ diff --git a/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/input.js b/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/input.js index 90bb710baa1d3..edde535f6212f 100644 --- a/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/input.js +++ b/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/input.js @@ -6,7 +6,7 @@ * This is a comment. */ -import { unstable_rootParams } from 'next/server' +import { lang } from 'next/root-params' export default function () { return null diff --git a/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.js b/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.js index ce04f4969bcce..25945c27bfb2e 100644 --- a/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.js +++ b/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.js @@ -2,7 +2,7 @@ 'use strict'; /** * This is a comment. - */ import { unstable_rootParams } from 'next/server'; + */ import { lang } from 'next/root-params'; export default function() { return null; } diff --git a/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.stderr b/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.stderr index 268d0f94149e5..12e2c99bfaafc 100644 --- a/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.stderr +++ b/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/root-params/output.stderr @@ -1,9 +1,9 @@ - x You're importing a component that needs "unstable_rootParams". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/ - | building-your-application/rendering/server-components + x You're importing a component that needs "next/root-params". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building- + | your-application/rendering/server-components | | ,-[input.js:9:1] 8 | - 9 | import { unstable_rootParams } from 'next/server' - : ^^^^^^^^^^^^^^^^^^^ + 9 | import { lang } from 'next/root-params' + : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `---- diff --git a/packages/next/server.d.ts b/packages/next/server.d.ts index a8a4567b498cd..655efd6973ea7 100644 --- a/packages/next/server.d.ts +++ b/packages/next/server.d.ts @@ -14,5 +14,4 @@ export { URLPattern } from 'next/dist/compiled/@edge-runtime/primitives/url' export { ImageResponse } from 'next/dist/server/web/spec-extension/image-response' export type { ImageResponseOptions } from 'next/dist/compiled/@vercel/og/types' export { after } from 'next/dist/server/after' -export { unstable_rootParams } from 'next/dist/server/request/root-params' export { connection } from 'next/dist/server/request/connection' diff --git a/packages/next/server.js b/packages/next/server.js index cd0dcecc135bd..2704955a25f36 100644 --- a/packages/next/server.js +++ b/packages/next/server.js @@ -13,8 +13,6 @@ const serverExports = { .URLPattern, after: require('next/dist/server/after').after, connection: require('next/dist/server/request/connection').connection, - unstable_rootParams: require('next/dist/server/request/root-params') - .unstable_rootParams, } // https://nodejs.org/api/esm.html#commonjs-namespaces @@ -30,4 +28,3 @@ exports.userAgent = serverExports.userAgent exports.URLPattern = serverExports.URLPattern exports.after = serverExports.after exports.connection = serverExports.connection -exports.unstable_rootParams = serverExports.unstable_rootParams diff --git a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts index 1b7ed9e73f98b..9818532846e4f 100644 --- a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts +++ b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts @@ -402,9 +402,7 @@ function isSubpath(parentLayoutPath: string, potentialChildLayoutPath: string) { ) } -function createServerDefinitions( - rootParams: { param: string; optional: boolean }[] -) { +function createServerDefinitions() { return ` declare module 'next/server' { @@ -423,13 +421,6 @@ function createServerDefinitions( export type { ImageResponseOptions } from 'next/dist/compiled/@vercel/og/types' export { after } from 'next/dist/server/after' export { connection } from 'next/dist/server/request/connection' - export function unstable_rootParams(): Promise<{ ${rootParams - .map( - ({ param, optional }) => - // ensure params with dashes are valid keys - `${param.includes('-') ? `'${param}'` : param}${optional ? '?' : ''}: string` - ) - .join(', ')} }> } ` } @@ -814,7 +805,7 @@ export class NextTypesPlugin { compilation.emitAsset( serverTypesPath, new sources.RawSource( - createServerDefinitions(rootParams) + createServerDefinitions() ) as unknown as webpack.sources.RawSource ) } diff --git a/packages/next/src/server/request/root-params.ts b/packages/next/src/server/request/root-params.ts index 559299dda5174..ee8393d64e1f9 100644 --- a/packages/next/src/server/request/root-params.ts +++ b/packages/next/src/server/request/root-params.ts @@ -14,189 +14,9 @@ import { type StaticPrerenderStore, } from '../app-render/work-unit-async-storage.external' import { makeHangingPromise } from '../dynamic-rendering-utils' -import type { OpaqueFallbackRouteParams } from './fallback-params' -import type { Params, ParamValue } from './params' -import { - describeStringPropertyAccess, - wellKnownProperties, -} from '../../shared/lib/utils/reflect-utils' +import type { ParamValue } from './params' +import { describeStringPropertyAccess } from '../../shared/lib/utils/reflect-utils' import { actionAsyncStorage } from '../app-render/action-async-storage.external' -import { warnOnce } from '../../build/output/log' - -interface CacheLifetime {} -const CachedParams = new WeakMap>() - -/** - * @deprecated import specific root params from `next/root-params` instead. - */ -export async function unstable_rootParams(): Promise { - warnOnce( - '`unstable_rootParams()` is deprecated and will be removed in an upcoming major release. Import specific root params from `next/root-params` instead.' - ) - const workStore = workAsyncStorage.getStore() - if (!workStore) { - throw new InvariantError('Missing workStore in unstable_rootParams') - } - - const workUnitStore = workUnitAsyncStorage.getStore() - - if (!workUnitStore) { - throw new Error( - `Route ${workStore.route} used \`unstable_rootParams()\` in Pages Router. This API is only available within App Router.` - ) - } - - switch (workUnitStore.type) { - case 'cache': - case 'unstable-cache': { - throw new Error( - `Route ${workStore.route} used \`unstable_rootParams()\` inside \`"use cache"\` or \`unstable_cache\`. Support for this API inside cache scopes is planned for a future version of Next.js.` - ) - } - case 'prerender': - case 'prerender-client': - case 'prerender-ppr': - case 'prerender-legacy': - return createPrerenderRootParams( - workUnitStore.rootParams, - workStore, - workUnitStore - ) - case 'private-cache': - case 'prerender-runtime': - case 'request': - return Promise.resolve(workUnitStore.rootParams) - default: - return workUnitStore satisfies never - } -} - -function createPrerenderRootParams( - underlyingParams: Params, - workStore: WorkStore, - prerenderStore: StaticPrerenderStore -): Promise { - switch (prerenderStore.type) { - case 'prerender-client': { - const exportName = '`unstable_rootParams`' - throw new InvariantError( - `${exportName} must not be used within a client component. Next.js should be preventing ${exportName} from being included in client components statically, but did not in this case.` - ) - } - case 'prerender': { - const fallbackParams = prerenderStore.fallbackRouteParams - if (fallbackParams) { - for (const key in underlyingParams) { - if (fallbackParams.has(key)) { - const cachedParams = CachedParams.get(underlyingParams) - if (cachedParams) { - return cachedParams - } - - const promise = makeHangingPromise( - prerenderStore.renderSignal, - workStore.route, - '`unstable_rootParams`' - ) - CachedParams.set(underlyingParams, promise) - - return promise - } - } - } - break - } - case 'prerender-ppr': { - const fallbackParams = prerenderStore.fallbackRouteParams - if (fallbackParams) { - for (const key in underlyingParams) { - if (fallbackParams.has(key)) { - // We have fallback params at this level so we need to make an erroring - // params object which will postpone if you access the fallback params - return makeErroringRootParams( - underlyingParams, - fallbackParams, - workStore, - prerenderStore - ) - } - } - } - break - } - case 'prerender-legacy': - break - default: - prerenderStore satisfies never - } - - // We don't have any fallback params so we have an entirely static safe params object - return Promise.resolve(underlyingParams) -} - -function makeErroringRootParams( - underlyingParams: Params, - fallbackParams: OpaqueFallbackRouteParams, - workStore: WorkStore, - prerenderStore: PrerenderStorePPR | PrerenderStoreLegacy -): Promise { - const cachedParams = CachedParams.get(underlyingParams) - if (cachedParams) { - return cachedParams - } - - const augmentedUnderlying = { ...underlyingParams } - - // We don't use makeResolvedReactPromise here because params - // supports copying with spread and we don't want to unnecessarily - // instrument the promise with spreadable properties of ReactPromise. - const promise = Promise.resolve(augmentedUnderlying) - CachedParams.set(underlyingParams, promise) - - Object.keys(underlyingParams).forEach((prop) => { - if (wellKnownProperties.has(prop)) { - // These properties cannot be shadowed because they need to be the - // true underlying value for Promises to work correctly at runtime - } else { - if (fallbackParams.has(prop)) { - Object.defineProperty(augmentedUnderlying, prop, { - get() { - const expression = describeStringPropertyAccess( - 'unstable_rootParams', - prop - ) - // In most dynamic APIs we also throw if `dynamic = "error"` however - // for params is only dynamic when we're generating a fallback shell - // and even when `dynamic = "error"` we still support generating dynamic - // fallback shells - // TODO remove this comment when cacheComponents is the default since there - // will be no `dynamic = "error"` - if (prerenderStore.type === 'prerender-ppr') { - // PPR Prerender (no cacheComponents) - postponeWithTracking( - workStore.route, - expression, - prerenderStore.dynamicTracking - ) - } else { - // Legacy Prerender - throwToInterruptStaticGeneration( - expression, - workStore, - prerenderStore - ) - } - }, - enumerable: true, - }) - } else { - ;(promise as any)[prop] = underlyingParams[prop] - } - } - }) - - return promise -} /** * Used for the compiler-generated `next/root-params` module. diff --git a/packages/next/src/server/web/exports/index.ts b/packages/next/src/server/web/exports/index.ts index 74f3d41181f88..38b1264ed87bf 100644 --- a/packages/next/src/server/web/exports/index.ts +++ b/packages/next/src/server/web/exports/index.ts @@ -7,4 +7,3 @@ export { userAgent, userAgentFromString } from '../spec-extension/user-agent' export { URLPattern } from '../spec-extension/url-pattern' export { after } from '../../after' export { connection } from '../../request/connection' -export { unstable_rootParams } from '../../request/root-params' diff --git a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/layout.tsx deleted file mode 100644 index 0502ea507ea10..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { ReactNode } from 'react' - -export default function Root({ children }: { children: ReactNode }) { - return ( - - {children} - - ) -} - -export async function generateStaticParams() { - return [ - { lang: 'en', locale: 'en-US' }, - { lang: 'es', locale: 'es-ES' }, - ] -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/[slug]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/[slug]/layout.tsx deleted file mode 100644 index d75c116266dca..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/[slug]/layout.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Layout({ children }) { - return
{children}
-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/[slug]/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/[slug]/page.tsx deleted file mode 100644 index 760aaed24e143..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/[slug]/page.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { headers } from 'next/headers' -import { unstable_rootParams } from 'next/server' - -export default async function Page({ params }) { - await headers() - const { slug } = await params - return ( -
-

{slug}

-

{JSON.stringify(await unstable_rootParams())}

-
- ) -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/layout.tsx deleted file mode 100644 index d75c116266dca..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/layout.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Layout({ children }) { - return
{children}
-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/page.tsx deleted file mode 100644 index 187b865111066..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/other/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - return
Other Page
-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/page.tsx deleted file mode 100644 index f241e008dc96f..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/generate-static-params/app/[lang]/[locale]/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - return

hello world {JSON.stringify(await unstable_rootParams())}

-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(dashboard)/[id]/data/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(dashboard)/[id]/data/page.tsx deleted file mode 100644 index f241e008dc96f..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(dashboard)/[id]/data/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - return

hello world {JSON.stringify(await unstable_rootParams())}

-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(dashboard)/[id]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(dashboard)/[id]/layout.tsx deleted file mode 100644 index f7b45d80141e4..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(dashboard)/[id]/layout.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { ReactNode } from 'react' - -export default function Root({ children }: { children: ReactNode }) { - return ( - - Dashboard Root: {children} - - ) -} - -export const revalidate = 0 -export async function generateStaticParams() { - return [{ id: '1' }] -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(marketing)/landing/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(marketing)/landing/page.tsx deleted file mode 100644 index f241e008dc96f..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(marketing)/landing/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - return

hello world {JSON.stringify(await unstable_rootParams())}

-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(marketing)/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(marketing)/layout.tsx deleted file mode 100644 index ab9238c0e14de..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/multiple-roots/app/(marketing)/layout.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { ReactNode } from 'react' - -export default function Root({ children }: { children: ReactNode }) { - return ( - - Marketing Root: {children} - - ) -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/layout.tsx deleted file mode 100644 index 614e0bf24928d..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/layout.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { ReactNode } from 'react' - -export default function Root({ children }: { children: ReactNode }) { - return ( - - {children} - - ) -} - -export const revalidate = 0 -export async function generateStaticParams() { - return [{ lang: 'en', locale: 'us' }] -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/[slug]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/[slug]/layout.tsx deleted file mode 100644 index d75c116266dca..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/[slug]/layout.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Layout({ children }) { - return
{children}
-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/[slug]/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/[slug]/page.tsx deleted file mode 100644 index f5dcadb7a7bbe..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/[slug]/page.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { cookies } from 'next/headers' -import { unstable_rootParams } from 'next/server' - -export default async function Page({ params }) { - await cookies() - const { slug } = await params - return ( -
-

{slug}

-

{JSON.stringify(await unstable_rootParams())}

-
- ) -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/layout.tsx deleted file mode 100644 index d75c116266dca..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/layout.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Layout({ children }) { - return
{children}
-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/page.tsx deleted file mode 100644 index 187b865111066..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/other/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - return
Other Page
-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/page.tsx deleted file mode 100644 index f241e008dc96f..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/simple/app/[lang]/[locale]/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - return

hello world {JSON.stringify(await unstable_rootParams())}

-} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/app/[lang]/[locale]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/app/[lang]/[locale]/layout.tsx deleted file mode 100644 index 0502ea507ea10..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/app/[lang]/[locale]/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { ReactNode } from 'react' - -export default function Root({ children }: { children: ReactNode }) { - return ( - - {children} - - ) -} - -export async function generateStaticParams() { - return [ - { lang: 'en', locale: 'en-US' }, - { lang: 'es', locale: 'es-ES' }, - ] -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/app/[lang]/[locale]/use-cache/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/app/[lang]/[locale]/use-cache/page.tsx deleted file mode 100644 index 334d9d6f222e0..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/app/[lang]/[locale]/use-cache/page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - const rootParams = await getCachedParams() - const data = await fetch( - 'https://next-data-api-endpoint.vercel.app/api/random' - ).then((res) => res.text()) - - return ( -

- - {rootParams.lang} {rootParams.locale} - {' '} - {data} -

- ) -} - -async function getCachedParams() { - 'use cache' - return unstable_rootParams() -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/next.config.js b/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/next.config.js deleted file mode 100644 index 9b469ab0242bf..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-build/next.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - experimental: { - useCache: true, - }, -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/layout.tsx b/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/layout.tsx deleted file mode 100644 index 716a8db36f52c..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/layout.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { ReactNode } from 'react' - -export default function Root({ children }: { children: ReactNode }) { - return ( - - {children} - - ) -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/request/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/request/page.tsx deleted file mode 100644 index 44a4d23cad589..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/request/page.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - const rootParams = await unstable_rootParams() - const data = await fetch( - 'https://next-data-api-endpoint.vercel.app/api/random' - ).then((res) => res.text()) - - return ( -

- - {rootParams.lang} {rootParams.locale} - {' '} - {data} -

- ) -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/unstable_cache/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/unstable_cache/page.tsx deleted file mode 100644 index 2ffdc10ec5fdd..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/unstable_cache/page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { unstable_rootParams } from 'next/server' -import { unstable_cache as cache } from 'next/cache' - -export default async function Page() { - const rootParams = await getCachedParams() - const data = await fetch( - 'https://next-data-api-endpoint.vercel.app/api/random' - ).then((res) => res.text()) - - return ( -

- - {rootParams.lang} {rootParams.locale} - {' '} - {data} -

- ) -} - -const getCachedParams = cache(async () => { - return unstable_rootParams() -}) diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/use-cache/page.tsx b/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/use-cache/page.tsx deleted file mode 100644 index 334d9d6f222e0..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/app/[lang]/[locale]/use-cache/page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { unstable_rootParams } from 'next/server' - -export default async function Page() { - const rootParams = await getCachedParams() - const data = await fetch( - 'https://next-data-api-endpoint.vercel.app/api/random' - ).then((res) => res.text()) - - return ( -

- - {rootParams.lang} {rootParams.locale} - {' '} - {data} -

- ) -} - -async function getCachedParams() { - 'use cache' - return unstable_rootParams() -} diff --git a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/next.config.js b/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/next.config.js deleted file mode 100644 index 9b469ab0242bf..0000000000000 --- a/test/e2e/app-dir/app-root-params/fixtures/use-cache-runtime/next.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - experimental: { - useCache: true, - }, -} diff --git a/test/e2e/app-dir/app-root-params/generate-static-params.test.ts b/test/e2e/app-dir/app-root-params/generate-static-params.test.ts deleted file mode 100644 index 12b95cc7ab015..0000000000000 --- a/test/e2e/app-dir/app-root-params/generate-static-params.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { nextTestSetup } from 'e2e-utils' -import { join } from 'path' - -describe('app-root-params - generateStaticParams', () => { - const { next, isNextDeploy, isTurbopack } = nextTestSetup({ - files: join(__dirname, 'fixtures', 'generate-static-params'), - }) - - it('should return rootParams', async () => { - const $ = await next.render$('/en/us') - expect($('p').text()).toBe('hello world {"lang":"en","locale":"us"}') - }) - - it('should only return rootParams and not other params', async () => { - const $ = await next.render$('/en/us/other/1') - expect($('#dynamic-params').text()).toBe('1') - expect($('#root-params').text()).toBe('{"lang":"en","locale":"us"}') - }) - - it('should be a cache hit for fully prerendered pages', async () => { - const response = await next.fetch('/en/us') - expect(response.status).toBe(200) - expect( - response.headers.get(isNextDeploy ? 'x-vercel-cache' : 'x-nextjs-cache') - ).toBe('HIT') - }) - - it("should be a cache miss for pages that aren't prerendered", async () => { - const response = await next.fetch('/en/us/other/1') - expect(response.status).toBe(200) - if (isNextDeploy) { - expect(response.headers.get('x-vercel-cache')).toBe('MISS') - } else { - expect(response.headers.get('x-nextjs-cache')).toBeFalsy() - } - }) - - // `next-types-plugin` currently only runs in Webpack. - // We skip deployment mode since we don't care about the deploy, we just want to - // check the file generated at build time. - if (!isNextDeploy && !isTurbopack) { - it('should correctly generate types', async () => { - expect(await next.hasFile('.next/types/server.d.ts')).toBe(true) - const fileContents = await next.readFile('.next/types/server.d.ts') - expect(fileContents).toContain( - `export function unstable_rootParams(): Promise<{ lang: string, locale: string }>` - ) - }) - } -}) diff --git a/test/e2e/app-dir/app-root-params/multiple-roots.test.ts b/test/e2e/app-dir/app-root-params/multiple-roots.test.ts deleted file mode 100644 index 6dc4d6985dc39..0000000000000 --- a/test/e2e/app-dir/app-root-params/multiple-roots.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { nextTestSetup } from 'e2e-utils' -import { join } from 'path' - -describe('app-root-params - multiple roots', () => { - const { next, isNextDeploy, isTurbopack } = nextTestSetup({ - files: join(__dirname, 'fixtures', 'multiple-roots'), - }) - - it('should have root params on dashboard pages', async () => { - const $ = await next.render$('/1/data') - expect($('body').text()).toContain('Dashboard Root') - expect($('p').text()).toBe('hello world {"id":"1"}') - }) - - it('should not have root params on marketing pages', async () => { - const $ = await next.render$('/landing') - expect($('body').text()).toContain('Marketing Root') - expect($('p').text()).toBe('hello world {}') - }) - - // `next-types-plugin` currently only runs in Webpack. - // We skip deployment mode since we don't care about the deploy, we just want to - // check the file generated at build time. - if (!isNextDeploy && !isTurbopack) { - it('should correctly generate types', async () => { - expect(await next.hasFile('.next/types/server.d.ts')).toBe(true) - const fileContents = await next.readFile('.next/types/server.d.ts') - expect(fileContents).toContain( - `export function unstable_rootParams(): Promise<{ id?: string }>` - ) - }) - } -}) diff --git a/test/e2e/app-dir/app-root-params/next.config.js b/test/e2e/app-dir/app-root-params/next.config.js deleted file mode 100644 index 807126e4cf0bf..0000000000000 --- a/test/e2e/app-dir/app-root-params/next.config.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @type {import('next').NextConfig} - */ -const nextConfig = {} - -module.exports = nextConfig diff --git a/test/e2e/app-dir/app-root-params/simple.test.ts b/test/e2e/app-dir/app-root-params/simple.test.ts deleted file mode 100644 index ecbf15b4b8d46..0000000000000 --- a/test/e2e/app-dir/app-root-params/simple.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { nextTestSetup } from 'e2e-utils' -import { assertNoRedbox } from 'next-test-utils' -import { join } from 'path' - -describe('app-root-params - simple', () => { - const { next, isNextDeploy, isTurbopack } = nextTestSetup({ - files: join(__dirname, 'fixtures', 'simple'), - }) - - it('should return rootParams', async () => { - const $ = await next.render$('/en/us') - expect($('p').text()).toBe('hello world {"lang":"en","locale":"us"}') - }) - - it('should only return rootParams and not other params', async () => { - const $ = await next.render$('/en/us/other/1') - expect($('#dynamic-params').text()).toBe('1') - expect($('#root-params').text()).toBe('{"lang":"en","locale":"us"}') - }) - - it('should render the not found page without errors', async () => { - const browser = await next.browser('/') - expect(await browser.elementByCss('h2').text()).toBe( - 'This page could not be found.' - ) - await assertNoRedbox(browser) - }) - - // `next-types-plugin` currently only runs in Webpack. - // We skip deployment mode since we don't care about the deploy, we just want to - // check the file generated at build time. - if (!isNextDeploy && !isTurbopack) { - it('should correctly generate types', async () => { - expect(await next.hasFile('.next/types/server.d.ts')).toBe(true) - const fileContents = await next.readFile('.next/types/server.d.ts') - expect(fileContents).toContain( - `export function unstable_rootParams(): Promise<{ lang: string, locale: string }>` - ) - }) - } -}) diff --git a/test/e2e/app-dir/app-root-params/use-cache.test.ts b/test/e2e/app-dir/app-root-params/use-cache.test.ts deleted file mode 100644 index 7a54ce5c2437d..0000000000000 --- a/test/e2e/app-dir/app-root-params/use-cache.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { nextTestSetup } from 'e2e-utils' -import { join } from 'path' -import { createSandbox } from 'development-sandbox' - -const isPPREnabled = process.env.__NEXT_EXPERIMENTAL_PPR === 'true' - -describe('app-root-params - cache - at runtime', () => { - const { next, isNextDev, skipped } = nextTestSetup({ - files: join(__dirname, 'fixtures', 'use-cache-runtime'), - skipStart: true, - // this test asserts on build failure logs, which aren't currently observable in `next.cliOutput`. - skipDeployment: true, - }) - - if (skipped) return - - if (isNextDev) { - it('should error when using rootParams within a "use cache" - dev', async () => { - await using sandbox = await createSandbox( - next, - undefined, - '/en/us/use-cache' - ) - const { session } = sandbox - await session.assertHasRedbox() - if (isPPREnabled) { - // When PPR is enabled we verify that we have at least one root param value from generateStaticParams - // Which this test does not define so we get a different error which preempts the root params error - expect(await session.getRedboxDescription()).toInclude( - 'Required root params (lang, locale) were not provided in generateStaticParams' - ) - } else { - expect(await session.getRedboxDescription()).toInclude( - 'Route /[lang]/[locale]/use-cache used `unstable_rootParams()` inside `"use cache"` or `unstable_cache`' - ) - } - }) - - it('should error when using rootParams within `unstable_cache` - dev', async () => { - await using sandbox = await createSandbox( - next, - undefined, - '/en/us/unstable_cache' - ) - const { session } = sandbox - await session.assertHasRedbox() - if (isPPREnabled) { - // When PPR is enabled we verify that we have at least one root param value from generateStaticParams - // Which this test does not define so we get a different error which preempts the root params error - expect(await session.getRedboxDescription()).toInclude( - 'Required root params (lang, locale) were not provided in generateStaticParams' - ) - } else { - expect(await session.getRedboxDescription()).toInclude( - 'Route /[lang]/[locale]/unstable_cache used `unstable_rootParams()` inside `"use cache"` or `unstable_cache`' - ) - } - }) - } else { - beforeAll(async () => { - try { - await next.start() - } catch (_) { - // We expect the build to fail - } - }) - - it('should error when using rootParams within a "use cache" - start', async () => { - if (isPPREnabled) { - // When PPR is enabled we verify that we have at least one root param value from generateStaticParams - // Which this test does not define so we get a different error which preempts the root params error - expect(next.cliOutput).toInclude( - 'Required root params (lang, locale) were not provided in generateStaticParams' - ) - } else { - await next.render$('/en/us/use-cache') - expect(next.cliOutput).toInclude( - 'Error: Route /[lang]/[locale]/use-cache used `unstable_rootParams()` inside `"use cache"` or `unstable_cache`' - ) - } - }) - - it('should error when using rootParams within `unstable_cache` - start', async () => { - if (isPPREnabled) { - // When PPR is enabled we verify that we have at least one root param value from generateStaticParams - // Which this test does not define so we get a different error which preempts the root params error - expect(next.cliOutput).toInclude( - 'Required root params (lang, locale) were not provided in generateStaticParams' - ) - } else { - await next.render$('/en/us/unstable_cache') - expect(next.cliOutput).toInclude( - 'Error: Route /[lang]/[locale]/unstable_cache used `unstable_rootParams()` inside `"use cache"` or `unstable_cache`' - ) - } - }) - } -}) - -describe('app-root-params - cache - at build', () => { - const { next, isNextDev } = nextTestSetup({ - files: join(__dirname, 'fixtures', 'use-cache-build'), - skipStart: true, - }) - - if (isNextDev) { - // we omit these tests in dev because they are duplicates semantically to the runtime fixture tested above - it('noop in dev', () => {}) - } else { - it('should error when building a project that uses rootParams within `"use cache"`', async () => { - try { - await next.start() - } catch { - // we expect the build to fail - } - expect(next.cliOutput).toInclude( - 'Error: Route /[lang]/[locale]/use-cache used `unstable_rootParams()` inside `"use cache"` or `unstable_cache`' - ) - }) - } -}) diff --git a/test/rspack-build-tests-manifest.json b/test/rspack-build-tests-manifest.json index 32fd060b3d192..04a10f459df1b 100644 --- a/test/rspack-build-tests-manifest.json +++ b/test/rspack-build-tests-manifest.json @@ -893,53 +893,6 @@ "flakey": [], "runtimeError": false }, - "test/e2e/app-dir/app-root-params/generate-static-params.test.ts": { - "passed": [ - "app-root-params - generateStaticParams should be a cache hit for fully prerendered pages", - "app-root-params - generateStaticParams should be a cache miss for pages that aren't prerendered", - "app-root-params - generateStaticParams should correctly generate types", - "app-root-params - generateStaticParams should only return rootParams and not other params", - "app-root-params - generateStaticParams should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/multiple-roots.test.ts": { - "passed": [ - "app-root-params - multiple roots should correctly generate types", - "app-root-params - multiple roots should have root params on dashboard pages", - "app-root-params - multiple roots should not have root params on marketing pages" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/simple.test.ts": { - "passed": [ - "app-root-params - simple should correctly generate types", - "app-root-params - simple should only return rootParams and not other params", - "app-root-params - simple should render the not found page without errors", - "app-root-params - simple should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/use-cache.test.ts": { - "passed": [ - "app-root-params - cache - at build should error when building a project that uses rootParams within `\"use cache\"`", - "app-root-params - cache - at runtime should error when using rootParams within `unstable_cache` - start", - "app-root-params - cache - at runtime should error when using rootParams within a \"use cache\" - start" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts": { "passed": [ "referencing a client component in an app route responds without error" diff --git a/test/rspack-dev-tests-manifest.json b/test/rspack-dev-tests-manifest.json index fe82fb074688e..c593ce4ef8440 100644 --- a/test/rspack-dev-tests-manifest.json +++ b/test/rspack-dev-tests-manifest.json @@ -3283,53 +3283,6 @@ "flakey": [], "runtimeError": false }, - "test/e2e/app-dir/app-root-params/generate-static-params.test.ts": { - "passed": [ - "app-root-params - generateStaticParams should be a cache hit for fully prerendered pages", - "app-root-params - generateStaticParams should be a cache miss for pages that aren't prerendered", - "app-root-params - generateStaticParams should correctly generate types", - "app-root-params - generateStaticParams should only return rootParams and not other params", - "app-root-params - generateStaticParams should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/multiple-roots.test.ts": { - "passed": [ - "app-root-params - multiple roots should correctly generate types", - "app-root-params - multiple roots should have root params on dashboard pages", - "app-root-params - multiple roots should not have root params on marketing pages" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/simple.test.ts": { - "passed": [ - "app-root-params - simple should correctly generate types", - "app-root-params - simple should only return rootParams and not other params", - "app-root-params - simple should render the not found page without errors", - "app-root-params - simple should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/use-cache.test.ts": { - "passed": [ - "app-root-params - cache - at build noop in dev", - "app-root-params - cache - at runtime should error when using rootParams within `unstable_cache` - dev", - "app-root-params - cache - at runtime should error when using rootParams within a \"use cache\" - dev" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts": { "passed": [ "referencing a client component in an app route responds without error" diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index 19d1eed4bf815..32608e064c40c 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -814,50 +814,6 @@ "flakey": [], "runtimeError": false }, - "test/e2e/app-dir/app-root-params/generate-static-params.test.ts": { - "passed": [ - "app-root-params - generateStaticParams should be a cache hit for fully prerendered pages", - "app-root-params - generateStaticParams should be a cache miss for pages that aren't prerendered", - "app-root-params - generateStaticParams should only return rootParams and not other params", - "app-root-params - generateStaticParams should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/multiple-roots.test.ts": { - "passed": [ - "app-root-params - multiple roots should have root params on dashboard pages", - "app-root-params - multiple roots should not have root params on marketing pages" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/simple.test.ts": { - "passed": [ - "app-root-params - simple should only return rootParams and not other params", - "app-root-params - simple should render the not found page without errors", - "app-root-params - simple should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/use-cache.test.ts": { - "passed": [ - "app-root-params - cache - at build should error when building a project that uses rootParams within `\"use cache\"`", - "app-root-params - cache - at runtime should error when using rootParams within `unstable_cache` - start", - "app-root-params - cache - at runtime should error when using rootParams within a \"use cache\" - start" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts": { "passed": [ "referencing a client component in an app route responds without error" diff --git a/test/turbopack-dev-tests-manifest.json b/test/turbopack-dev-tests-manifest.json index f97e93e183f2d..6436012b79e60 100644 --- a/test/turbopack-dev-tests-manifest.json +++ b/test/turbopack-dev-tests-manifest.json @@ -4827,50 +4827,6 @@ "flakey": [], "runtimeError": false }, - "test/e2e/app-dir/app-root-params/generate-static-params.test.ts": { - "passed": [ - "app-root-params - generateStaticParams should be a cache hit for fully prerendered pages", - "app-root-params - generateStaticParams should be a cache miss for pages that aren't prerendered", - "app-root-params - generateStaticParams should only return rootParams and not other params", - "app-root-params - generateStaticParams should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/multiple-roots.test.ts": { - "passed": [ - "app-root-params - multiple roots should have root params on dashboard pages", - "app-root-params - multiple roots should not have root params on marketing pages" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/simple.test.ts": { - "passed": [ - "app-root-params - simple should only return rootParams and not other params", - "app-root-params - simple should render the not found page without errors", - "app-root-params - simple should return rootParams" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "test/e2e/app-dir/app-root-params/use-cache.test.ts": { - "passed": [ - "app-root-params - cache - at build noop in dev", - "app-root-params - cache - at runtime should error when using rootParams within `unstable_cache` - dev", - "app-root-params - cache - at runtime should error when using rootParams within a \"use cache\" - dev" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts": { "passed": [ "referencing a client component in an app route responds without error"