diff --git a/errors/invalid-multi-match.md b/errors/invalid-multi-match.md new file mode 100644 index 0000000000000..cf9596b23d77a --- /dev/null +++ b/errors/invalid-multi-match.md @@ -0,0 +1,27 @@ +# Invalid Multi-match + +#### Why This Error Occurred + +In one of your custom-routes you specified a multi-match `/:path*` and used it in your `destination` without adding the `*` in your `destination` e.g. `destination: '/another/:path'` + +#### Possible Ways to Fix It + +Add `*` to your usage of the multi-match param in your `destination`. + +**Before** + +```js +{ + source: '/:path*', + destination: '/another/:path' +} +``` + +**After** + +```js +{ + source: '/:path*', + destination: '/another/:path*' +} +``` diff --git a/packages/next/next-server/server/next-server.ts b/packages/next/next-server/server/next-server.ts index 104d00957c747..02e8cbf0ed459 100644 --- a/packages/next/next-server/server/next-server.ts +++ b/packages/next/next-server/server/next-server.ts @@ -412,7 +412,20 @@ export default class Server { name: `${route.type} ${route.source} route`, fn: async (_req, res, params, _parsedUrl) => { let destinationCompiler = pathToRegexp.compile(route.destination) - let newUrl = destinationCompiler(params) + let newUrl + + try { + newUrl = destinationCompiler(params) + } catch (err) { + if ( + err.message.match(/Expected .*? to not repeat, but got array/) + ) { + throw new Error( + `To use a multi-match in the destination you must add \`*\` at the end of the param name to signify it should repeat. https://err.sh/zeit/next.js/invalid-multi-match` + ) + } + throw err + } if (route.type === 'redirect') { res.setHeader('Location', newUrl) diff --git a/test/integration/invalid-multi-match/next.config.js b/test/integration/invalid-multi-match/next.config.js new file mode 100644 index 0000000000000..46cb98f27cefa --- /dev/null +++ b/test/integration/invalid-multi-match/next.config.js @@ -0,0 +1,12 @@ +module.exports = { + experimental: { + rewrites() { + return [ + { + source: '/:hello*', + destination: '/:hello', + }, + ] + }, + }, +} diff --git a/test/integration/invalid-multi-match/pages/hello.js b/test/integration/invalid-multi-match/pages/hello.js new file mode 100644 index 0000000000000..1b69a605b6fe9 --- /dev/null +++ b/test/integration/invalid-multi-match/pages/hello.js @@ -0,0 +1,15 @@ +import { useRouter } from 'next/router' + +console.log('hello from hello.js') + +const Page = () => { + const { query } = useRouter() + return ( + <> +