Skip to content

Commit d95aed6

Browse files
authored
Fix router isReady and react 18 not being detected with no config (#35762)
This fixes `router.isReady` being incorrect in dev mode due to the `isAutoExport` field being false from `hasConcurrentFeatures` being flagged similar to the static 404 in #35749. While investigating this I also noticed we aren't properly detecting react 18 when no `next.config.js` is present. ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Errors have helpful link attached, see `contributing.md` Fixes: #35754 x-ref: #35749
1 parent fe012ff commit d95aed6

File tree

6 files changed

+76
-20
lines changed

6 files changed

+76
-20
lines changed

packages/next/server/config.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ function assignDefaults(userConfig: { [key: string]: any }) {
188188
}
189189
}
190190

191+
const hasReactRoot = shouldUseReactRoot()
192+
if (hasReactRoot) {
193+
// users might not have the `experimental` key in their config
194+
result.experimental = result.experimental || {}
195+
result.experimental.reactRoot = true
196+
}
197+
191198
if (result?.images) {
192199
const images: ImageConfig = result.images
193200

@@ -681,13 +688,6 @@ export default async function loadConfig(
681688
)
682689
}
683690

684-
const hasReactRoot = shouldUseReactRoot()
685-
if (hasReactRoot) {
686-
// users might not have the `experimental` key in their config
687-
userConfig.experimental = userConfig.experimental || {}
688-
userConfig.experimental.reactRoot = true
689-
}
690-
691691
if (userConfig.amp?.canonicalBase) {
692692
const { canonicalBase } = userConfig.amp || ({} as any)
693693
userConfig.amp = userConfig.amp || {}
@@ -727,7 +727,9 @@ export default async function loadConfig(
727727
}
728728
}
729729

730-
const completeConfig = defaultConfig as NextConfigComplete
730+
// always call assignDefaults to ensure settings like
731+
// reactRoot can be updated correctly even with no next.config.js
732+
const completeConfig = assignDefaults(defaultConfig) as NextConfigComplete
731733
completeConfig.configFileName = configFileName
732734
setHttpAgentOptions(completeConfig.httpAgentOptions)
733735
return completeConfig

packages/next/server/render.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ export async function renderToHTML(
561561
defaultAppGetInitialProps &&
562562
!isSSG &&
563563
!getServerSideProps &&
564-
!hasConcurrentFeatures
564+
!isServerComponent
565565

566566
for (const methodName of [
567567
'getStaticProps',

packages/next/taskfile.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,18 +1861,8 @@ export async function pages_document(task, opts) {
18611861
.target('dist/pages')
18621862
}
18631863

1864-
export async function pages_document_server(task, opts) {
1865-
await task
1866-
.source('pages/_document-concurrent.tsx')
1867-
.swc('client', { dev: opts.dev, keepImportAssertions: true })
1868-
.target('dist/pages')
1869-
}
1870-
18711864
export async function pages(task, opts) {
1872-
await task.parallel(
1873-
['pages_app', 'pages_error', 'pages_document', 'pages_document_server'],
1874-
opts
1875-
)
1865+
await task.parallel(['pages_app', 'pages_error', 'pages_document'], opts)
18761866
}
18771867

18781868
export async function telemetry(task, opts) {

test/development/basic/hmr.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,38 @@ describe('basic HMR', () => {
3030
})
3131
afterAll(() => next.destroy())
3232

33+
it('should have correct router.isReady for auto-export page', async () => {
34+
let browser = await webdriver(next.url, '/auto-export-is-ready')
35+
36+
expect(await browser.elementByCss('#ready').text()).toBe('yes')
37+
expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({})
38+
39+
browser = await webdriver(next.url, '/auto-export-is-ready?hello=world')
40+
41+
await check(async () => {
42+
return browser.elementByCss('#ready').text()
43+
}, 'yes')
44+
expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({
45+
hello: 'world',
46+
})
47+
})
48+
49+
it('should have correct router.isReady for getStaticProps page', async () => {
50+
let browser = await webdriver(next.url, '/gsp-is-ready')
51+
52+
expect(await browser.elementByCss('#ready').text()).toBe('yes')
53+
expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({})
54+
55+
browser = await webdriver(next.url, '/gsp-is-ready?hello=world')
56+
57+
await check(async () => {
58+
return browser.elementByCss('#ready').text()
59+
}, 'yes')
60+
expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({
61+
hello: 'world',
62+
})
63+
})
64+
3365
describe('Hot Module Reloading', () => {
3466
describe('delete a page and add it back', () => {
3567
it('should load the page properly', async () => {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { useRouter } from 'next/router'
2+
3+
export default function Page(props) {
4+
const router = useRouter()
5+
return (
6+
<>
7+
<p>auto-export router.isReady</p>
8+
<p id="query">{JSON.stringify(router.query)}</p>
9+
<p id="ready">{router.isReady ? 'yes' : 'no'}</p>
10+
</>
11+
)
12+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { useRouter } from 'next/router'
2+
3+
export default function Page(props) {
4+
const router = useRouter()
5+
return (
6+
<>
7+
<p>getStaticProps router.isReady</p>
8+
<p id="query">{JSON.stringify(router.query)}</p>
9+
<p id="ready">{router.isReady ? 'yes' : 'no'}</p>
10+
</>
11+
)
12+
}
13+
14+
export function getStaticProps() {
15+
return {
16+
props: {
17+
now: Date.now(),
18+
},
19+
}
20+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy