Given the business definitions:
- There are people with names (name + surname) written in PascalCase, such as "JohnDoe" and "AnalyseKitting"
- There are pages such as "home", "profile", "about", "faq" ...
Given the business needs:
- When user inputs "www.ourpage.com/JohnDoe" it redirects to "www.ourpage.com/profile/JohnDoe"
- when user inputs "www.ourpage.com/home" there is no redirection
What I expect
// next.config.js
module.exports = {
...
async redirects() {
return [
{
source: "/:personName((?:[A-Z][a-z]+){2})",
destination: "/profile/:personName",
permanent: true
}
]
this code should match PascalCase only, and redirect to /profile/:personName only when there is a positive match.
It does not work, as when writing /about it's redirected to /profile/about.
here you have an SSCCE sandbox https://codesandbox.io/s/redirects-not-working-as-expected-6z909
What partially works but is not maintainable
to do a negative lookahead of anything that is not from Nextjs or from our list of pages. PascalCase naming is not achieved, though
// next.config.js
module.exports = {
...
async redirects() {
return [
{
source: "/:personName((?!_next|about|profile).+)", // not maintainable
destination: "/profile/:personName",
permanent: true
}
]
Here is a SSCCE working example codesandbox https://codesandbox.io/s/redirects-working-with-negative-lookahead-bi9xf?file=/next.config.js
Working workaround but NOT in redirects()
It's possible to intercept at server's getServerSideProps function by intercepting all requests with a page named [anyName].js or [...anyName].js, like in the following example
// [...root].js
const personNameRegexp = /^(?:[A-Z][a-z]+){2}$/;
export const getServerSideProps = async ({ params }) => {
const isPersonName = personNameRegexp.test(params.root);
if (isPersonName) {
return {
redirect: {
destination: `profile/${params.root}`,
permanent: false
}
};
}
return {
props: {}
};
};
Here is a SSCCE working example codesandbox https://codesandbox.io/s/redirections-based-on-regex-cmn6c
Other workarounds tried without luck
I tried to use the has objects but personName is not a query param, apparently, and can't be matched like this:
has: [
{
type: "query",
key: "personName",
value: "(?:[A-Z][a-z]+){2}",
},
],