Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fallback to functional document when no custom document with react 18 #36348

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/next/server/render.tsx
Expand Up @@ -1301,7 +1301,14 @@ export async function renderToHTML(
}
}

if ((isServerComponent || process.browser) && Document.getInitialProps) {
if (
// If it's server component, edge runtime or using default document with react 18,
// try to fallback to built-in functional document
(isServerComponent ||
process.browser ||
(builtinDocument && hasConcurrentFeatures)) &&
Document.getInitialProps
) {
if (builtinDocument) {
Document = builtinDocument
} else {
Expand Down
6 changes: 6 additions & 0 deletions test/integration/react-18/app/pages/index.js
@@ -1,7 +1,13 @@
import ReactDOM from 'react-dom'
import Image from 'next/image'

function sideEffectCall() {
console.log('sideEffectCall')
}

export default function Index() {
sideEffectCall()

if (typeof window !== 'undefined') {
window.didHydrate = true
}
Expand Down
8 changes: 8 additions & 0 deletions test/integration/react-18/test/basics.js
Expand Up @@ -5,6 +5,14 @@ import cheerio from 'cheerio'
import { renderViaHTTP } from 'next-test-utils'

export default (context, env) => {
it('should render page on server side only once if there is no custom document', async () => {
await renderViaHTTP(context.appPort, '/')
const firstIndex = context.stdout.indexOf('sideEffectCall')
const lastIndex = context.stdout.lastIndexOf('sideEffectCall')
// log only once
expect(firstIndex === lastIndex).toBe(true)
})

it('no warnings for image related link props', async () => {
await renderViaHTTP(context.appPort, '/')
expect(context.stderr).not.toContain('Warning: Invalid DOM property')
Expand Down
8 changes: 5 additions & 3 deletions test/lib/next-test-utils.js
Expand Up @@ -754,10 +754,10 @@ function runSuite(suiteName, context, options) {
describe(`${suiteName} ${env}`, () => {
beforeAll(async () => {
options.beforeAll?.(env)
context.stdout = ''
context.stderr = ''
const onStderr = (msg) => {
context.stderr += msg
}
const onStdout = (msg) => (context.stdout += msg)
const onStderr = (msg) => (context.stderr += msg)
if (env === 'prod') {
context.appPort = await findPort()
const { stdout, stderr, code } = await nextBuild(appDir, [], {
Expand All @@ -768,11 +768,13 @@ function runSuite(suiteName, context, options) {
context.stderr = stderr
context.code = code
context.server = await nextStart(context.appDir, context.appPort, {
onStdout,
onStderr,
})
} else if (env === 'dev') {
context.appPort = await findPort()
context.server = await launchApp(context.appDir, context.appPort, {
onStdout,
onStderr,
})
}
Expand Down