From 050a720b0732fcc15b8da8767e63b5110dcbfbbb Mon Sep 17 00:00:00 2001 From: Xavier Coppens Date: Sun, 17 Nov 2024 16:09:51 +0000 Subject: [PATCH 1/2] Fixed interception on a catchAll route --- .../next/src/lib/generate-interception-routes-rewrites.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/src/lib/generate-interception-routes-rewrites.ts b/packages/next/src/lib/generate-interception-routes-rewrites.ts index ee1458fabb319..0415f78b7a425 100644 --- a/packages/next/src/lib/generate-interception-routes-rewrites.ts +++ b/packages/next/src/lib/generate-interception-routes-rewrites.ts @@ -13,8 +13,8 @@ function toPathToRegexpPath(path: string): string { const paramName = capture.replace(/\W+/g, '_') // handle catch-all segments (e.g. /foo/bar/[...baz] or /foo/bar/[[...baz]]) - if (paramName.startsWith('...')) { - return `:${paramName.slice(3)}*` + if (capture.startsWith('...')) { + return `:${capture.slice(3)}*` } return ':' + paramName }) From 8b137b305abe11abfefe04118ae4c06a8cb47605 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:52:06 -0800 Subject: [PATCH 2/2] add test --- .../app/[...catchAll]/page.tsx | 16 ++++++++ .../app/layout.tsx | 9 ++++ .../app/page.tsx | 5 +++ .../(..)showcase/[...catchAll]/page.tsx | 13 ++++++ .../app/templates/[...catchAll]/page.tsx | 18 ++++++++ .../app/templates/page.tsx | 13 ++++++ ...erception-routes-multiple-catchall.test.ts | 41 +++++++++++++++++++ 7 files changed, 115 insertions(+) create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/app/[...catchAll]/page.tsx create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/app/layout.tsx create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/app/page.tsx create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/(..)showcase/[...catchAll]/page.tsx create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/[...catchAll]/page.tsx create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/page.tsx create mode 100644 test/e2e/app-dir/interception-routes-multiple-catchall/interception-routes-multiple-catchall.test.ts diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/app/[...catchAll]/page.tsx b/test/e2e/app-dir/interception-routes-multiple-catchall/app/[...catchAll]/page.tsx new file mode 100644 index 0000000000000..7ce8657bba628 --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/app/[...catchAll]/page.tsx @@ -0,0 +1,16 @@ +import Link from 'next/link' +import React from 'react' + +async function Page({ params }: { params: Promise<{ catchAll: string[] }> }) { + const { catchAll } = await params + return ( +
+ Showcase Simple Page + + templates {catchAll.join(' -> ')} + +
+ ) +} + +export default Page diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/app/layout.tsx b/test/e2e/app-dir/interception-routes-multiple-catchall/app/layout.tsx new file mode 100644 index 0000000000000..57909d386d843 --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/app/layout.tsx @@ -0,0 +1,9 @@ +export default function RootLayout({ + children, +}: Readonly<{ children: React.ReactNode }>) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/app/page.tsx b/test/e2e/app-dir/interception-routes-multiple-catchall/app/page.tsx new file mode 100644 index 0000000000000..1dddc3a4b547e --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/app/page.tsx @@ -0,0 +1,5 @@ +import Link from 'next/link' + +export default function HomePage() { + return Go to test page +} diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/(..)showcase/[...catchAll]/page.tsx b/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/(..)showcase/[...catchAll]/page.tsx new file mode 100644 index 0000000000000..e2234ce24779a --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/(..)showcase/[...catchAll]/page.tsx @@ -0,0 +1,13 @@ +import Link from 'next/link' +import React from 'react' + +async function Page() { + return ( +
+ Showcase Intercepting Page + Single +
+ ) +} + +export default Page diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/[...catchAll]/page.tsx b/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/[...catchAll]/page.tsx new file mode 100644 index 0000000000000..27a53c8563ddd --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/[...catchAll]/page.tsx @@ -0,0 +1,18 @@ +import Link from 'next/link' +import React from 'react' + +async function Page({ params }: { params: Promise<{ catchAll: string[] }> }) { + const { catchAll } = await params + return ( +
+ Simple Page + + To Same Path {catchAll.join(' -> ')} + + To Single Path + multi-slug +
+ ) +} + +export default Page diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/page.tsx b/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/page.tsx new file mode 100644 index 0000000000000..b42bc555c943b --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/app/templates/page.tsx @@ -0,0 +1,13 @@ +import Link from 'next/link' +import React from 'react' + +function Page() { + return ( +
+ Simple Page + showcase/new +
+ ) +} + +export default Page diff --git a/test/e2e/app-dir/interception-routes-multiple-catchall/interception-routes-multiple-catchall.test.ts b/test/e2e/app-dir/interception-routes-multiple-catchall/interception-routes-multiple-catchall.test.ts new file mode 100644 index 0000000000000..7746d13a54879 --- /dev/null +++ b/test/e2e/app-dir/interception-routes-multiple-catchall/interception-routes-multiple-catchall.test.ts @@ -0,0 +1,41 @@ +import { nextTestSetup } from 'e2e-utils' + +describe('interception-routes-multiple-catchall', () => { + const { next } = nextTestSetup({ + files: __dirname, + }) + + describe('multi-param catch-all', () => { + it('should intercept when navigating to the same path with route interception', async () => { + const browser = await next.browser('/templates/multi/slug') + await browser.elementByCss("[href='/showcase/multi/slug']").click() + await browser.waitForElementByCss('#intercepting-page') + }) + + it('should intercept when navigating to a single param path', async () => { + const browser = await next.browser('/templates/multi/slug') + await browser.elementByCss("[href='/showcase/single']").click() + await browser.waitForElementByCss('#intercepting-page') + }) + + it('should intercept when navigating to a multi-param path', async () => { + const browser = await next.browser('/templates/multi/slug') + await browser.elementByCss("[href='/showcase/another/slug']").click() + await browser.waitForElementByCss('#intercepting-page') + }) + }) + + describe('single param catch-all', () => { + it('should intercept when navigating to a multi-param path', async () => { + const browser = await next.browser('/templates/single') + await browser.elementByCss("[href='/showcase/another/slug']").click() + await browser.waitForElementByCss('#intercepting-page') + }) + + it('should intercept when navigating to a single param path', async () => { + const browser = await next.browser('/templates/single') + await browser.elementByCss("[href='/showcase/single']").click() + await browser.waitForElementByCss('#intercepting-page') + }) + }) +})