diff --git a/packages/next/shared/lib/dynamic.tsx b/packages/next/shared/lib/dynamic.tsx
index ba5871238998580..771e4b5aaa375a3 100644
--- a/packages/next/shared/lib/dynamic.tsx
+++ b/packages/next/shared/lib/dynamic.tsx
@@ -122,7 +122,6 @@ export default function dynamic
(
`Disallowed suspense option usage with next/dynamic in blocking mode`
)
}
- suspenseOptions.suspense = false
}
if (suspenseOptions.suspense) {
return loadableFn(suspenseOptions)
diff --git a/test/integration/react-18/app/pages/suspense/unwrapped.js b/test/integration/react-18/app/pages/suspense/unwrapped.js
index 3909e80679a6a9d..93c32bbbc50100b 100644
--- a/test/integration/react-18/app/pages/suspense/unwrapped.js
+++ b/test/integration/react-18/app/pages/suspense/unwrapped.js
@@ -1,10 +1,19 @@
-import React from 'react'
+import React, { Suspense } from 'react'
import dynamic from 'next/dynamic'
+// flag for testing
+const wrapped = true
+
const Hello = dynamic(() => import('../../components/hello'), {
suspense: true,
})
export default function Unwrapped() {
- return
+ if (!wrapped) return
+
+ return (
+
+
+
+ )
}
diff --git a/test/integration/react-18/test/blocking.js b/test/integration/react-18/test/blocking.js
index 3adb476c5a018b2..c4feeb2e8a301f6 100644
--- a/test/integration/react-18/test/blocking.js
+++ b/test/integration/react-18/test/blocking.js
@@ -20,8 +20,6 @@ export default (context, render) => {
const $ = await get$('/suspense/thrown')
const html = $('body').html()
expect(html).toContain('loading')
- expect(
- JSON.parse($('#__NEXT_DATA__').text()).dynamicIds
- ).not.toBeUndefined()
+ expect(JSON.parse($('#__NEXT_DATA__').text()).dynamicIds).toBeUndefined()
})
}
diff --git a/test/integration/react-18/test/index.test.js b/test/integration/react-18/test/index.test.js
index d0f889adcccd1bc..a63d78b92372c84 100644
--- a/test/integration/react-18/test/index.test.js
+++ b/test/integration/react-18/test/index.test.js
@@ -23,9 +23,8 @@ const nodeArgs = ['-r', join(__dirname, 'require-hook.js')]
const appDir = join(__dirname, '../app')
const nextConfig = new File(join(appDir, 'next.config.js'))
const dynamicHello = new File(join(appDir, 'components/dynamic-hello.js'))
+const unwrappedPage = new File(join(appDir, 'pages/suspense/unwrapped.js'))
-const SUSPENSE_ERROR_MESSAGE =
- 'Disallowed suspense option usage with next/dynamic'
const UNSUPPORTED_PRERELEASE =
"You are using an unsupported prerelease of 'react-dom'"
const USING_CREATE_ROOT = 'Using the createRoot API for React'
@@ -81,12 +80,15 @@ describe('React 18 Support', () => {
expect(output).not.toMatch(UNSUPPORTED_PRERELEASE)
})
- it('suspense is not allowed in blocking rendering mode', async () => {
- const appPort = await findPort()
- const app = await launchApp(appDir, appPort)
- const html = await renderViaHTTP(appPort, '/suspense/unwrapped')
- await killApp(app)
- expect(html).toContain(SUSPENSE_ERROR_MESSAGE)
+ test('suspense is not allowed in blocking rendering mode (prod)', async () => {
+ const { stderr, code } = await nextBuild(appDir, [], {
+ nodeArgs,
+ stderr: true,
+ })
+ expect(code).toBe(1)
+ expect(stderr).toContain(
+ 'Disallowed suspense option usage with next/dynamic'
+ )
})
})
@@ -118,10 +120,21 @@ describe('React 18 Support', () => {
})
describe('Basics', () => {
- runTests('default setting with react 18', 'dev', (context) => basics(context))
- runTests('default setting with react 18', 'prod', (context) =>
- basics(context)
- )
+ runTests('default setting with react 18', (context) => basics(context))
+
+ it('suspense is not allowed in blocking rendering mode (dev)', async () => {
+ // set dynamic.suspense = true but not wrapping with
+ unwrappedPage.replace('wrapped = true', 'wrapped = false')
+ const appPort = await findPort()
+ const app = await launchApp(appDir, appPort, { nodeArgs })
+ const html = await renderViaHTTP(appPort, '/suspense/unwrapped')
+ unwrappedPage.restore()
+ await killApp(app)
+ // expect(html).toContain('Disallowed suspense option usage with next/dynamic')
+ expect(html).toContain(
+ 'A React component suspended while rendering, but no fallback UI was specified'
+ )
+ })
})
describe('Blocking mode', () => {
@@ -132,11 +145,7 @@ describe('Blocking mode', () => {
dynamicHello.restore()
})
- runTests('concurrentFeatures is disabled', 'dev', (context) =>
- blocking(context, (p, q) => renderViaHTTP(context.appPort, p, q))
- )
-
- runTests('concurrentFeatures is disabled', 'prod', (context) =>
+ runTests('concurrentFeatures is disabled', (context) =>
blocking(context, (p, q) => renderViaHTTP(context.appPort, p, q))
)
})
@@ -156,15 +165,12 @@ describe('Concurrent mode', () => {
dynamicHello.restore()
})
- runTests('concurrentFeatures is enabled', 'dev', (context) =>
- concurrent(context, (p, q) => renderViaHTTP(context.appPort, p, q))
- )
- runTests('concurrentFeatures is enabled', 'prod', (context) =>
+ runTests('concurrentFeatures is enabled', (context) =>
concurrent(context, (p, q) => renderViaHTTP(context.appPort, p, q))
)
})
-function runTests(name, mode, fn) {
+function runTest(mode, name, fn) {
const context = { appDir }
describe(`${name} (${mode})`, () => {
beforeAll(async () => {
@@ -186,3 +192,8 @@ function runTests(name, mode, fn) {
fn(context)
})
}
+
+function runTests(name, fn) {
+ runTest('dev', name, fn)
+ runTest('prod', name, fn)
+}