Skip to content

Commit 60ab8f6

Browse files
huozhiztanner
andauthored
Fix loading navigation with metadata and prefetch (#66447)
### What & Why Fixes NEXT-3498 Fixed loading shows up and disappear during client navigation, when you defined `prefetch` is enabled and slow `generateMetadata` is defined. In #64532, where in layout-router, we removed the place of infinite suspense, adding it back so that the app can still remain suspensy during navigation. #### Behavior before fix Prefetch -> Link Navigation -> Show `loading.js` -> RSC payload fetched (no page content) -> the page content will display later when the promise is resolved #### Behavior after the fix Prefetch -> Link Navigation -> Show `loading.js` -> RSC payload fetched -> suspensy page content still triggering `loading.js` -> display the resolved page content when the promise is resolved --------- Co-authored-by: Zack Tanner <[email protected]>
1 parent b911485 commit 60ab8f6

File tree

3 files changed

+17
-17
lines changed

3 files changed

+17
-17
lines changed

packages/next/src/client/components/layout-router.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,10 +450,10 @@ function InnerLayoutRouter({
450450
// It's important that we mark this as resolved, in case this branch is replayed, we don't want to continously re-apply
451451
// the patch to the tree.
452452
childNode.lazyDataResolved = true
453-
454-
// Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered.
455-
use(unresolvedThenable) as never
456453
}
454+
// Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered.
455+
// A falsey `resolvedRsc` indicates missing data -- we should not commit that branch, and we need to wait for the data to arrive.
456+
use(unresolvedThenable) as never
457457
}
458458

459459
// We use `useDeferredValue` to handle switching between the prefetched and
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
'use client'
2-
import { useEffect } from 'react'
3-
41
export default function Loading() {
5-
useEffect(() => {
6-
window.shownLoading = true
7-
}, [])
82
return <div id="loading">Loading</div>
93
}

test/e2e/app-dir/navigation/navigation.test.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -864,16 +864,22 @@ describe('app dir - navigation', () => {
864864
it('should render the final state of the page with correct metadata', async () => {
865865
const browser = await next.browser('/metadata-await-promise')
866866

867-
await browser
868-
.elementByCss("[href='/metadata-await-promise/nested']")
869-
.click()
867+
// dev doesn't trigger the loading boundary as it's not prefetched
868+
if (isNextDev) {
869+
await browser
870+
.elementByCss("[href='/metadata-await-promise/nested']")
871+
.click()
872+
} else {
873+
const loadingText = await browser
874+
.elementByCss("[href='/metadata-await-promise/nested']")
875+
.click()
876+
.waitForElementByCss('#loading')
877+
.text()
870878

871-
await retry(async () => {
872-
// dev doesn't trigger the loading boundary as it's not prefetched
873-
if (!isNextDev) {
874-
expect(await browser.eval(`window.shownLoading`)).toBe(true)
875-
}
879+
expect(loadingText).toBe('Loading')
880+
}
876881

882+
await retry(async () => {
877883
expect(await browser.elementById('page-content').text()).toBe('Content')
878884

879885
expect(await browser.elementByCss('title').text()).toBe('Async Title')

0 commit comments

Comments
 (0)