Next.js - Downsides to Handling All Routes with a Single Slug.js File?

19 replies
Last updated: Mar 22, 2021
Curious: Are there drawbacks to just having a single
[[…slug]].js
file that handles all your routes than manually duplicating logic from file to file? The more I work with Next the less I’m sure the file based routing is worth it.
AI Update

This question is about general Next.js routing architecture rather than Sanity-specific functionality. You'd get better answers in Next.js-focused communities like the Next.js GitHub Discussions, the Next.js Discord, or Stack Overflow with the next.js tag.

That said, if you're building a Sanity-powered site with Next.js and finding yourself duplicating logic across route files, there are some Sanity-specific patterns that might help reduce that duplication:

  • Shared data fetching utilities: Create reusable functions for your GROQ queries and Sanity client calls that can be imported into any route file
  • Component-based templates: Keep your route files thin by moving shared logic into components that handle their own data fetching with Sanity's Visual Editing patterns
  • Content-driven routing with Sanity: Use Sanity's document types to drive your routing strategy rather than fighting against Next.js file-based routing

The routing architecture decision itself (catch-all vs. discrete files) is a Next.js concern that applies regardless of your CMS, so the Next.js community will have more targeted advice for your specific use case!

I do [pageSlug].js for all pages that share the same template as well. I usually have similar pages under /blog/[postSlug].js, and /case-studies/[caseSlug].js
I’m finding so much shared code in all these files though. For example /news/slug.js is going to pretty much the exact same components as /category/slug.js ... so at what point do you just shove everything in one mega catch all file I wonder..
Yeah for sure they are very similar
one mega catch all file
I've never seen
[[...slug]].js
though, is that a thing?
Yep, it’ll catch routes with multiple paths like
/news/research/new-release
Ha cool, so what do the params look like in
export const getStaticProps = async ({ _params_ }) => {
?
for example that could look like this (file-based):
/news/[categorySlug]/[postSlug]
It requires an array of slugs “parts”. Which you can then use to inform your staticProps query.
I think the only drawback are...• 404 errors work slgihtly different, they go through your optional catch all page, too. Or I had some bugs with notFound: true at least particularly.
• It may be worth checking the webpack bundles before/after. In case they're using each page filesystem name as entry point
I use a catch all
[...slug].js
for just about every project. the code in the return looks something like this:
  return (
      <Layout page={data.content} site={doc.site}>
        {data.content._type === 'page' ? (
          <PageContent {...data.content} />
        ) : (
          <PostContent {...data.content} />
        )}
      </Layout>
  );
Within sanity I can define any directory structure I need to
Obviously this example only is using
Pages
and
Posts
, but I just add on as needed
Yeah cool. And you don’t see any drawbacks?
It’s something that to me “feels” wrong, but in execution seems so much more right!

Makes me think that Gatsby’s move from a single file to generate all paths, to file based routing, is misguided...
I've not run into a problem yet with this workflow.
If things share components all you'd have to do is add an
or
statement where it's checking the type of the
content
or whatever you've named your stuff
I’m doing all my routes in a single
[...slug.js]
file now and it’s so clean you could eat off it
user S
Now just rename it to
gatsby-node.js
and you’re off to the races. 😅
That’s precisely what I’ve recreated 😄

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?