From be83e50f19de66c7115a7bce4d95c0c7038cad43 Mon Sep 17 00:00:00 2001 From: cvolant Date: Wed, 2 Nov 2022 15:57:41 +0100 Subject: [PATCH] Fix as option with optional catch all routes `as` option used to throw with url object syntax: optional attribute were not taken into account when checking missing parameters in router change method. Fixes #41624 --- packages/next/shared/lib/router/router.ts | 2 +- .../rewrites-manual-href-as/next.config.js | 4 ++++ .../pages/news/[[...slugs]].js | 22 +++++++++++++++++++ .../pages/preview/[slug].js | 9 ++++++++ .../test/index.test.js | 12 ++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 test/integration/rewrites-manual-href-as/pages/news/[[...slugs]].js diff --git a/packages/next/shared/lib/router/router.ts b/packages/next/shared/lib/router/router.ts index e7d9610913e7d8b..7e91cf88bf50d93 100644 --- a/packages/next/shared/lib/router/router.ts +++ b/packages/next/shared/lib/router/router.ts @@ -1505,7 +1505,7 @@ export default class Router implements BaseRouter { if (!routeMatch || (shouldInterpolate && !interpolatedAs.result)) { const missingParams = Object.keys(routeRegex.groups).filter( - (param) => !query[param] + (param) => !query[param] && !routeRegex.groups[param].optional ) if (missingParams.length > 0 && !isMiddlewareMatch) { diff --git a/test/integration/rewrites-manual-href-as/next.config.js b/test/integration/rewrites-manual-href-as/next.config.js index 0716516e76e651c..da626b657914508 100644 --- a/test/integration/rewrites-manual-href-as/next.config.js +++ b/test/integration/rewrites-manual-href-as/next.config.js @@ -5,6 +5,10 @@ module.exports = { source: '/rewrite-me', destination: '/another', }, + { + source: '/blog/:slugs*', + destination: '/news/:slugs*', + }, ] }, } diff --git a/test/integration/rewrites-manual-href-as/pages/news/[[...slugs]].js b/test/integration/rewrites-manual-href-as/pages/news/[[...slugs]].js new file mode 100644 index 000000000000000..1d0a43584e4a2d9 --- /dev/null +++ b/test/integration/rewrites-manual-href-as/pages/news/[[...slugs]].js @@ -0,0 +1,22 @@ +import Link from 'next/link' +import { useRouter } from 'next/router' + +export default function News() { + const { asPath, pathname, query } = useRouter() + + return ( +
+

news page

+

{asPath}

+

{pathname}

+

{JSON.stringify(query)}

+ ← Back home +
+ ) +} + +export async function getServerSideProps() { + return { + props: {}, + } +} diff --git a/test/integration/rewrites-manual-href-as/pages/preview/[slug].js b/test/integration/rewrites-manual-href-as/pages/preview/[slug].js index 3fdfd7c328774f7..a71db0613880613 100644 --- a/test/integration/rewrites-manual-href-as/pages/preview/[slug].js +++ b/test/integration/rewrites-manual-href-as/pages/preview/[slug].js @@ -55,6 +55,15 @@ export default function Page(props) { go to /preview/321 as /rewrite-me
+ + + go to /news as /blog + +
) } diff --git a/test/integration/rewrites-manual-href-as/test/index.test.js b/test/integration/rewrites-manual-href-as/test/index.test.js index cddfb0818a232e4..9f92b7c66778a00 100644 --- a/test/integration/rewrites-manual-href-as/test/index.test.js +++ b/test/integration/rewrites-manual-href-as/test/index.test.js @@ -144,6 +144,18 @@ const runTests = () => { expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({ slug: '321', }) + + await browser.back().waitForElementByCss('#preview') + + await browser + .elementByCss('#to-news-as-blog') + .click() + .waitForElementByCss('#news') + + expect(await browser.elementByCss('#news').text()).toBe('news page') + expect(await browser.elementByCss('#asPath').text()).toBe('/blog') + expect(await browser.eval('window.beforeNav')).toBe(1) + expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({}) }) }