Top level catch-all route alongside a dynamic route? Using Next14 with app router
Unanswered
Russian Blue posted this in #help-forum
Russian BlueOP
What is the correct way to have a top level catch-all route (i.e. /app/[...slugs]/page.tsx) alongside a dynamic route (i.e. /app/[slug]/page.tsx)? I've managed to get it working by trying to retrieve the 'slug' from our CMS in the dynamic route (/app/[slug]), if that is not found we then call the Page export from the catch-all route passing in params something like:
I've asked this same question in the NextJS subreddit with some more detail: https://www.reddit.com/r/nextjs/comments/1dj4kzt/
<Page params={{ slugs: [params.slug] }} /> . This works but feels a bit wrong, especially in my use case I have this at 3 levels so the catch-all (/app/[...slugs]) also tries to fetch data from the CMS if it is not found it then passes this onto another route (in my case /app/product/[slug]).I've asked this same question in the NextJS subreddit with some more detail: https://www.reddit.com/r/nextjs/comments/1dj4kzt/
1 Reply
@Russian Blue What is the correct way to have a top level catch-all route (i.e. /app/[...slugs]/page.tsx) alongside a dynamic route (i.e. /app/[slug]/page.tsx)? I've managed to get it working by trying to retrieve the 'slug' from our CMS in the dynamic route (/app/[slug]), if that is not found we then call the Page export from the catch-all route passing in params something like: `<Page params={{ slugs: [params.slug] }} />` . This works but feels a bit wrong, especially in my use case I have this at 3 levels so the catch-all (/app/[...slugs]) also tries to fetch data from the CMS if it is not found it then passes this onto another route (in my case /app/product/[slug]).
I've asked this same question in the NextJS subreddit with some more detail: https://www.reddit.com/r/nextjs/comments/1dj4kzt/
i dont think nextjs supports two dynamic segments at the same level. the reason is that for a request
you probably have to unify them all into one single
for static generation, you can do something like
with
/something, nextjs doesn't know whether to route it to the [slug] or the [...slug]. afaik the precedence of predetermined segments over dynamic segments doesn't extend to different segment types.you probably have to unify them all into one single
app/[...slug]/page.tsx file, where you can do something likeif (slug.length === 1)
return <Article slug={slug[0]} />
if (slug.length >= 3) notFound();
const [category, subCatOrProduct] = slug;
// do something to determine whether it is a subcategory or a product
// then return the correct component.for static generation, you can do something like
// generateStaticParams()
const allArticles = await getAllArticlesSlugs();
const allCategories = await getAllCategoriesSlugs();
const allCatAndSubCat = await Promise.all(
allCategories.map(
async cat => [cat, await getSubCategories(cat)]
)
);
return [
...allArticles.map(a => ({ slug: [a.slug] })),
...allCategories.map(cat => ({ slug: [cat.slug] })),
...allCatAndSubCat.map(cs => ({ slug: cs })),
];with
dynamicParams = true (or you can go one step further and add the product URLs and whatnot inside the returned array too.