From 02c2f11ec969d2c5767f9dfbec275bbc65171e66 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 18 Jan 2024 21:11:22 +0100 Subject: [PATCH] Enable missing suspense bailout by default (#60840) `experimental.missingSuspenseWithCSRBailout` should be enabled by default to help users to disciver unwrapped suspense boundaries. Add more notes in the error doc about deprecation and temporary workaround to disable it. Closes NEXT-2157 --------- Co-authored-by: JJ Kasper --- errors/missing-suspense-with-csr-bailout.mdx | 2 ++ packages/next/src/server/config-shared.ts | 5 +++-- .../missing-suspense-with-csr-bailout/next.config.js | 6 +----- .../params-hooks-compat/app/app/[slug]/page.js | 9 ++++++++- .../params-hooks-compat/shared/params-component.js | 1 - .../(shallow)/pushstate-new-searchparams/page.tsx | 12 +++++++++++- .../app/(shallow)/pushstate-string-url/page.tsx | 12 +++++++++++- .../(shallow)/replacestate-new-searchparams/page.tsx | 12 +++++++++++- .../app/(shallow)/replacestate-string-url/page.tsx | 12 +++++++++++- 9 files changed, 58 insertions(+), 13 deletions(-) diff --git a/errors/missing-suspense-with-csr-bailout.mdx b/errors/missing-suspense-with-csr-bailout.mdx index bf5aa02a0132..d95cec71ba1b 100644 --- a/errors/missing-suspense-with-csr-bailout.mdx +++ b/errors/missing-suspense-with-csr-bailout.mdx @@ -10,6 +10,8 @@ Certain methods like `useSearchParams()` opt Next.js into client-side rendering. Make sure that the method is wrapped in a suspense boundary. This way Next.js will only opt the component into client-side rendering up to the suspense boundary. +> Note: There's an option `experimental.missingSuspenseWithCSRBailout` to disable the bailout behavior while you are investigating the missing suspense boundary. But it will be removed in next major version as this is a performance de-opt. + ### Useful Links - [`useSearchParams`](https://nextjs.org/docs/app/api-reference/functions/use-search-params) diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index 9590b0aa1be0..7378caefcf33 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -387,7 +387,8 @@ export interface ExperimentalConfig { * * When this flag is set to `true`, Next.js will break the build instead of warning, to force the developer to add a suspense boundary above the method call. * - * @default false + * @note This flag will be removed in Next.js 15. + * @default true */ missingSuspenseWithCSRBailout?: boolean } @@ -866,7 +867,7 @@ export const defaultConfig: NextConfig = { ? true : false, webpackBuildWorker: undefined, - missingSuspenseWithCSRBailout: false, + missingSuspenseWithCSRBailout: true, }, } diff --git a/test/e2e/app-dir/missing-suspense-with-csr-bailout/next.config.js b/test/e2e/app-dir/missing-suspense-with-csr-bailout/next.config.js index 459c99acaf15..3477de6e00c9 100644 --- a/test/e2e/app-dir/missing-suspense-with-csr-bailout/next.config.js +++ b/test/e2e/app-dir/missing-suspense-with-csr-bailout/next.config.js @@ -1,8 +1,4 @@ /** @type {import("next").NextConfig} */ -const config = { - experimental: { - missingSuspenseWithCSRBailout: true, - }, -} +const config = {} module.exports = config diff --git a/test/e2e/app-dir/params-hooks-compat/app/app/[slug]/page.js b/test/e2e/app-dir/params-hooks-compat/app/app/[slug]/page.js index d8a123efbcd2..b64e1edbf756 100644 --- a/test/e2e/app-dir/params-hooks-compat/app/app/[slug]/page.js +++ b/test/e2e/app-dir/params-hooks-compat/app/app/[slug]/page.js @@ -1,5 +1,12 @@ 'use client' +import { Suspense } from 'react' import { ParamsComponent } from '../../../shared/params-component' -export default ParamsComponent +export default function Page() { + return ( + + + + ) +} diff --git a/test/e2e/app-dir/params-hooks-compat/shared/params-component.js b/test/e2e/app-dir/params-hooks-compat/shared/params-component.js index b3cebe777124..3ea7943d2b89 100644 --- a/test/e2e/app-dir/params-hooks-compat/shared/params-component.js +++ b/test/e2e/app-dir/params-hooks-compat/shared/params-component.js @@ -1,4 +1,3 @@ -import React from 'react' import { useParams, useSearchParams } from 'next/navigation' export function ParamsComponent() { diff --git a/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-new-searchparams/page.tsx b/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-new-searchparams/page.tsx index 4c1435c94d10..bfe28e92ff83 100644 --- a/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-new-searchparams/page.tsx +++ b/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-new-searchparams/page.tsx @@ -1,7 +1,9 @@ 'use client' + +import { Suspense } from 'react' import { useSearchParams } from 'next/navigation' -export default function Page() { +function InnerPage() { const searchParams = useSearchParams() return ( <> @@ -24,3 +26,11 @@ export default function Page() { ) } + +export default function Page() { + return ( + + + + ) +} diff --git a/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-string-url/page.tsx b/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-string-url/page.tsx index 20f9f07f324d..2eacff1bf934 100644 --- a/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-string-url/page.tsx +++ b/test/e2e/app-dir/shallow-routing/app/(shallow)/pushstate-string-url/page.tsx @@ -1,7 +1,9 @@ 'use client' + +import { Suspense } from 'react' import { useSearchParams } from 'next/navigation' -export default function Page() { +function InnerPage() { const searchParams = useSearchParams() return ( <> @@ -57,3 +59,11 @@ export default function Page() { ) } + +export default function Page() { + return ( + + + + ) +} diff --git a/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-new-searchparams/page.tsx b/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-new-searchparams/page.tsx index fe92608bc8a0..68d1b4477b0c 100644 --- a/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-new-searchparams/page.tsx +++ b/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-new-searchparams/page.tsx @@ -1,7 +1,9 @@ 'use client' + +import { Suspense } from 'react' import { useSearchParams } from 'next/navigation' -export default function Page() { +function InnerPage() { const searchParams = useSearchParams() return ( <> @@ -24,3 +26,11 @@ export default function Page() { ) } + +export default function Page() { + return ( + + + + ) +} diff --git a/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-string-url/page.tsx b/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-string-url/page.tsx index 72c9dcf715c3..415e681959f5 100644 --- a/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-string-url/page.tsx +++ b/test/e2e/app-dir/shallow-routing/app/(shallow)/replacestate-string-url/page.tsx @@ -1,7 +1,9 @@ 'use client' + +import { Suspense } from 'react' import { useSearchParams } from 'next/navigation' -export default function Page() { +function InnerPage() { const searchParams = useSearchParams() return ( <> @@ -57,3 +59,11 @@ export default function Page() { ) } + +export default function Page() { + return ( + + + + ) +}