-
Notifications
You must be signed in to change notification settings - Fork 27k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix router prefetch cache key to work with route interception
- Loading branch information
Showing
18 changed files
with
234 additions
and
13 deletions.
There are no files selected for viewing
24 changes: 24 additions & 0 deletions
24
packages/next/src/client/components/router-reducer/reducers/create-prefetch-cache-key.ts
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,24 @@ | ||
import { createHrefFromUrl } from '../create-href-from-url' | ||
|
||
/** | ||
* Creates a cache key for the router prefetch cache | ||
* | ||
* @param url - The URL being navigated to | ||
* @param nextUrl - an internal URL, primarily used for handling rewrites. Defaults to '/'. | ||
* @return The generated prefetch cache key. | ||
*/ | ||
export function createPrefetchCacheKey(url: URL, nextUrl: string | null) { | ||
const pathnameFromUrl = createHrefFromUrl( | ||
url, | ||
// Ensures the hash is not part of the cache key as it does not impact the server fetch | ||
false | ||
) | ||
|
||
// Route interception depends on `nextUrl` values which aren't a 1:1 mapping to a URL | ||
// The cache key that we store needs to use `nextUrl` to properly distinguish cache entries | ||
if (nextUrl && nextUrl !== '/') { | ||
return `${nextUrl}${pathnameFromUrl}` | ||
} | ||
|
||
return pathnameFromUrl | ||
} |
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
27 changes: 27 additions & 0 deletions
27
test/e2e/app-dir/interception-route-prefetch-cache/app/Modal.tsx
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,27 @@ | ||
'use client' | ||
|
||
import { useRouter } from 'next/navigation' | ||
|
||
interface ModalProps { | ||
title: string | ||
context: string | ||
} | ||
|
||
export function Modal({ title, context }: ModalProps) { | ||
const router = useRouter() | ||
|
||
return ( | ||
<div> | ||
<div className="modal"> | ||
<h1>{title}</h1> | ||
<h2>{context}</h2> | ||
</div> | ||
<div | ||
className="modal-overlay" | ||
onClick={() => { | ||
router.back() | ||
}} | ||
/> | ||
</div> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
test/e2e/app-dir/interception-route-prefetch-cache/app/bar/@modal/(...)post/[id]/page.tsx
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 { Modal } from '../../../../Modal' | ||
|
||
export default function BarPagePostInterceptSlot({ | ||
params: { id }, | ||
}: { | ||
params: { | ||
id: string | ||
} | ||
}) { | ||
return <Modal title={`Post ${id}`} context="Intercepted on Bar Page" /> | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/interception-route-prefetch-cache/app/bar/@modal/default.tsx
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,3 @@ | ||
export default function Default() { | ||
return null | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/interception-route-prefetch-cache/app/bar/default.tsx
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,3 @@ | ||
export default function Default() { | ||
return null | ||
} |
14 changes: 14 additions & 0 deletions
14
test/e2e/app-dir/interception-route-prefetch-cache/app/bar/layout.tsx
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,14 @@ | ||
export default function BarLayout({ | ||
modal, | ||
children, | ||
}: { | ||
modal: React.ReactNode | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
<> | ||
<div id="slot">{modal}</div> | ||
<div id="children">{children}</div> | ||
</> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/interception-route-prefetch-cache/app/bar/page.tsx
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 BarPage() { | ||
return ( | ||
<div> | ||
<h1>Bar Page</h1> | ||
<Link href="/post/1">Post 1</Link> | ||
</div> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
test/e2e/app-dir/interception-route-prefetch-cache/app/foo/@modal/(...)post/[id]/page.tsx
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 { Modal } from '../../../../Modal' | ||
|
||
export default function FooPagePostInterceptSlot({ | ||
params: { id }, | ||
}: { | ||
params: { | ||
id: string | ||
} | ||
}) { | ||
return <Modal title={`Post ${id}`} context="Intercepted on Foo Page" /> | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/interception-route-prefetch-cache/app/foo/@modal/default.tsx
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,3 @@ | ||
export default function Default() { | ||
return null | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/interception-route-prefetch-cache/app/foo/default.tsx
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,3 @@ | ||
export default function Default() { | ||
return null | ||
} |
14 changes: 14 additions & 0 deletions
14
test/e2e/app-dir/interception-route-prefetch-cache/app/foo/layout.tsx
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,14 @@ | ||
export default function FooLayout({ | ||
modal, | ||
children, | ||
}: { | ||
modal: React.ReactNode | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
<> | ||
<div id="slot">{modal}</div> | ||
<div id="children">{children}</div> | ||
</> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/interception-route-prefetch-cache/app/foo/page.tsx
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 FooPage() { | ||
return ( | ||
<div> | ||
<h1>Foo Page</h1> | ||
<Link href="/post/1">Post 1</Link> | ||
</div> | ||
) | ||
} |
13 changes: 13 additions & 0 deletions
13
test/e2e/app-dir/interception-route-prefetch-cache/app/layout.tsx
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,13 @@ | ||
import Link from 'next/link' | ||
|
||
export default function RootLayout({ children }) { | ||
return ( | ||
<html> | ||
<head /> | ||
<body> | ||
<Link href="/">home</Link> | ||
{children} | ||
</body> | ||
</html> | ||
) | ||
} |
18 changes: 18 additions & 0 deletions
18
test/e2e/app-dir/interception-route-prefetch-cache/app/page.tsx
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,18 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Home() { | ||
return ( | ||
<ul> | ||
<li> | ||
<Link href="/foo">foo</Link> | ||
</li> | ||
<li> | ||
<Link href="/bar">bar</Link> | ||
</li> | ||
<br /> | ||
<li> | ||
<Link href="/post/1">post 1</Link> | ||
</li> | ||
</ul> | ||
) | ||
} |
13 changes: 13 additions & 0 deletions
13
test/e2e/app-dir/interception-route-prefetch-cache/app/post/[id]/page.tsx
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,13 @@ | ||
export default function PostPage({ | ||
params: { id }, | ||
}: { | ||
params: { | ||
id: string | ||
} | ||
}) { | ||
return ( | ||
<div> | ||
<h1>Post {id}</h1> | ||
</div> | ||
) | ||
} |
45 changes: 45 additions & 0 deletions
45
test/e2e/app-dir/interception-route-prefetch-cache/interception-route-prefetch-cache.test.ts
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,45 @@ | ||
import { createNextDescribe } from 'e2e-utils' | ||
import { check } from 'next-test-utils' | ||
|
||
createNextDescribe( | ||
'interception-route-prefetch-cache', | ||
{ | ||
files: __dirname, | ||
}, | ||
({ next }) => { | ||
it('should render the correct interception when two distinct layouts share the same path structure', async () => { | ||
const browser = await next.browser('/') | ||
|
||
await browser.elementByCss('[href="/foo"]').click() | ||
|
||
await check(() => browser.elementById('children').text(), /Foo Page/) | ||
|
||
await browser.elementByCss('[href="/post/1"]').click() | ||
|
||
// Ensure the existing page content is still the same | ||
await check(() => browser.elementById('children').text(), /Foo Page/) | ||
|
||
// Verify we got the right interception | ||
await check( | ||
() => browser.elementById('slot').text(), | ||
/Intercepted on Foo Page/ | ||
) | ||
|
||
// Go back home. At this point, the router cache should have content from /foo | ||
// Now we want to ensure that /bar doesn't share that same prefetch cache entry | ||
await browser.elementByCss('[href="/"]').click() | ||
await browser.elementByCss('[href="/bar"]').click() | ||
|
||
await check(() => browser.elementById('children').text(), /Bar Page/) | ||
await browser.elementByCss('[href="/post/1"]').click() | ||
|
||
// Ensure the existing page content is still the same. If the prefetch cache resolved the wrong cache node | ||
// then we'd see the content from /foo | ||
await check(() => browser.elementById('children').text(), /Bar Page/) | ||
await check( | ||
() => browser.elementById('slot').text(), | ||
/Intercepted on Bar Page/ | ||
) | ||
}) | ||
} | ||
) |