Skip to content

Commit

Permalink
interception routes: fix interception for dynamic routes (#58198)
Browse files Browse the repository at this point in the history
This PR fixes the bug in which interception routes of the form `(.)[param]` would not intercept navigations.

The bug happened because we would not create a dynamic route matcher for the intercepted route, so we would never match the correct dynamic route when hitting the server, falling back to the base one. 

The fix consists of fixing the logic that checks for a dynamic route so that it checks the correct path when handling an interception route.

There's probably a better fix here, advice welcome

fixes #52533
  • Loading branch information
feedthejim authored Nov 8, 2023
1 parent a6a8c84 commit 536d2db
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/next/src/lib/create-client-router-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { isDynamicRoute } from '../shared/lib/router/utils'
import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash'
import type { Redirect } from './load-custom-routes'
import { tryToParsePath } from './try-to-parse-path'
import {
extractInterceptionRouteInformation,
isInterceptionRouteAppPath,
} from '../server/future/helpers/interception-routes'

export function createClientRouterFilter(
paths: string[],
Expand All @@ -16,8 +20,12 @@ export function createClientRouterFilter(
const staticPaths = new Set<string>()
const dynamicPaths = new Set<string>()

for (const path of paths) {
for (let path of paths) {
if (isDynamicRoute(path)) {
if (isInterceptionRouteAppPath(path)) {
path = extractInterceptionRouteInformation(path).interceptedRoute
}

let subPath = ''
const pathParts = path.split('/')

Expand Down
9 changes: 9 additions & 0 deletions packages/next/src/shared/lib/router/utils/is-dynamic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import {
extractInterceptionRouteInformation,
isInterceptionRouteAppPath,
} from '../../../../server/future/helpers/interception-routes'

// Identify /[param]/ in route string
const TEST_ROUTE = /\/\[[^/]+?\](?=\/|$)/

export function isDynamicRoute(route: string): boolean {
if (isInterceptionRouteAppPath(route)) {
route = extractInterceptionRouteInformation(route).interceptedRoute
}

return TEST_ROUTE.test(route)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function Page({ params: { id } }) {
return (
<div>
<h2>intercepting-siblings</h2>
<p id="intercepted-sibling">{id}</p>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Default() {
return <div>default</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function Page({ params: { id } }) {
return (
<div>
<h2>main slot</h2>
<p id="main-slot">{id}</p>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Link from 'next/link'

export default function Layout({ children, modal }) {
return (
<div>
<h1>intercepting-siblings</h1>
<div style={{ border: '1px solid black', padding: '1rem' }}>
{children}
</div>
<hr />
<div style={{ border: '1px solid black', padding: '1rem' }}>{modal}</div>
<h1>links</h1>
<ul>
<li>
<Link href="/intercepting-siblings">/intercepting-siblings</Link>
</li>
<li>
<Link href="/intercepting-siblings/1">/intercepting-siblings/1</Link>
</li>
<li>
<Link href="/intercepting-siblings/2">/intercepting-siblings/2</Link>
</li>
<li>
<Link href="/intercepting-siblings/3">/intercepting-siblings/3</Link>
</li>
</ul>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <div>main page</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,42 @@ createNextDescribe(
'intercepted'
)
})

it('should support intercepting local dynamic sibling routes', async () => {
const browser = await next.browser('/intercepting-siblings')

await check(
() =>
browser
.elementByCss('[href="/intercepting-siblings/1"]')
.click()
.waitForElementByCss('#intercepted-sibling')
.text(),
'1'
)
await check(
() =>
browser
.elementByCss('[href="/intercepting-siblings/2"]')
.click()
.waitForElementByCss('#intercepted-sibling')
.text(),
'2'
)
await check(
() =>
browser
.elementByCss('[href="/intercepting-siblings/3"]')
.click()
.waitForElementByCss('#intercepted-sibling')
.text(),
'3'
)

await next.browser('/intercepting-siblings/1')

await check(() => browser.waitForElementByCss('#main-slot').text(), '1')
})
})
}
)

0 comments on commit 536d2db

Please sign in to comment.