We have a project that contains one dynamic route [productId], and inside this page, we have several other pages that include optional catch-all routes. Here is the structure on the pages folder:
[productId]
contentOne
[[...slugOne]]
The issue is, the optional catch-all are not workink properly whenever the pages are statically generated. Ex:
productId/contentOne does not work, but productOne/contentOne/extra works
The problem occurs only when deployed in vercel. All routes work perfectly on local.
Here is the getStaticPaths:
export async function getStaticPaths() {
return {
paths: [],
fallback: true,
}
}
Here is the getStaticProps:
export async function getStaticProps({ locale }) {
return {
props: {
test: 'test',
...(await serverSideTranslations(locale, ['common'])),
}
}
}
We have an open issue for this: https://github.com/vercel/next.js/issues/30631
Meanwhile, we had to use rewrites (this goes into the next.config file):
async rewrites() {
return {
beforeFiles: [
{
source: '/:productId/contentOne',
destination: '/:productId/contentOne/index'
}
]
}
When using getStaticPaths to generate your pages, setting { fallback: true } does not result in a 404. During development, it works because development uses a version of Automatic Static Optimization where Next is serving up a server-rendered site even if the pages are going to be static.
If you're running a SSR site with Next, then setting fallback will serve up a static page with empty props. That's the expected behavior (if that's what's happening for you) and it's incumbent on you to handle that page either by redirecting client-side or showing your own 404-type or missing content page.
If you're using next export to build and export your pages, then setting fallback does nothing (the expected behavior when using next export) which means that the page just won't exist and your server should handle the 404, either by serving up a 404 error page or redirecting the user somewhere else.
I'm not sure what you mean by "doesn't work" - is it giving you a 404 error or an empty page? Either way, the above is why.