forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
disable static prefetching behavior for dynamic segments (vercel#58609)
### What? When a layout segment forces dynamic rendering (such as with `force-dynamic` or `revalidate: 0`), navigating to sub-pages of that layout will attempt to re-render the layout, also resulting in side effects re-running. This means if your layout relies on a data fetch and you render the result of that data in the layout, it will unexpectedly change when navigating between sub-paths, as described in vercel#57326. As a separate issue (but caused by the same underlying mechanism), when using `searchParams` on a dynamic page, changes to those search params will be erroneously ignored when navigating, as described in vercel#57075 ### Why? As a performance optimization we generate static prefetch files for dynamic segments ([original PR](vercel#54403)). This makes it so that when prefetching is turned on, the prefetch can be served quickly from the edge without needing to invoke unnecessarily. We're able to eagerly serve things that can be safely prefetched. This is nice for cases where a path has a `loading.js` that we can eagerly render while waiting for the dynamic data to be loaded. This causes a problem with layouts that opt into dynamic rendering: when the page loads and a prefetch is kicked off for the sub-page, it'll load the static prefetch, which won't be generated with the same router state as the dynamically rendered page. This causes a mismatch between the two trees, and when navigating within the same segment, a refetch will be added to the router because it thinks that it's navigating to a new layout. This also causes issues for dynamic pages that use `searchParams`. The static prefetch will be generated without any knowledge of search params, and when the prefetch occurs, we still match to the prefetch generated without search params. This will make the router think that no change occurs, and the UI will not update to reflect the change. ### How? There's ongoing work by @acdlite to refactor the client router. Hopefully it will be easier to re-land this once that work is finished. For now, I've reverted the behavior as it doesn't seem to be worth the bugs it currently causes. I've also added tests so that when we do re-land this behavior, we can catch these subtleties. Fixes vercel#57326 Fixes vercel#57075 Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
f6b50ae
commit 3043fee
Showing
13 changed files
with
229 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react' | ||
|
||
export const dynamic = 'force-dynamic' | ||
|
||
export default async function Layout({ children }) { | ||
console.log('re-fetching in layout') | ||
const data = await fetch( | ||
'https://next-data-api-endpoint.vercel.app/api/random' | ||
) | ||
const randomNumber = await data.text() | ||
|
||
return ( | ||
<div> | ||
<p id="random-number">{randomNumber}</p> | ||
|
||
{children} | ||
</div> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
test/e2e/app-dir/app-prefetch/app/force-dynamic/search-params/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Home({ searchParams }) { | ||
return ( | ||
<> | ||
<div id="search-params-data">{JSON.stringify(searchParams)}</div> | ||
<Link href="?foo=true">Add search params</Link> | ||
<Link href="/force-dynamic/search-params">Clear Params</Link> | ||
</> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Page() { | ||
return ( | ||
<div id="test-page"> | ||
Hello from /force-dynamic/test-page{' '} | ||
<Link href="/force-dynamic/test-page/sub-page">To Sub Page</Link> | ||
</div> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/sub-page/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Page() { | ||
return ( | ||
<div id="sub-page"> | ||
Hello from /force-dynamic/test-page/sub-page{' '} | ||
<Link href="/force-dynamic/test-page">Back to Test Page</Link> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react' | ||
|
||
export const revalidate = 0 | ||
|
||
export default async function Layout({ children }) { | ||
console.log('re-fetching in layout') | ||
const data = await fetch( | ||
'https://next-data-api-endpoint.vercel.app/api/random' | ||
) | ||
const randomNumber = await data.text() | ||
|
||
return ( | ||
<div> | ||
<p id="random-number">{randomNumber}</p> | ||
|
||
{children} | ||
</div> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
test/e2e/app-dir/app-prefetch/app/revalidate-0/search-params/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Home({ searchParams }) { | ||
return ( | ||
<> | ||
<div id="search-params-data">{JSON.stringify(searchParams)}</div> | ||
<Link href="?foo=true">Add search params</Link> | ||
<Link href="/revalidate-0/search-params">Clear Params</Link> | ||
</> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Page() { | ||
return ( | ||
<div id="test-page"> | ||
Hello from /revalidate-0/test-page{' '} | ||
<Link href="/revalidate-0/test-page/sub-page">To Sub Page</Link> | ||
</div> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/sub-page/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Page() { | ||
return ( | ||
<div id="sub-page"> | ||
Hello from /revalidate-0/test-page/sub-page{' '} | ||
<Link href="/revalidate-0/test-page">Back to Test Page</Link> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.