j.grima
j.grima

Reputation: 1941

Next.js dynamic routes using a different URL

I am currently updating a React project to use Next.js. I've stumbled on a slight issue with Dynamic Routing which so far I can't find any solutions online.

I have a number of info pages that use the same component and display different content based on the slug. Using react-router these can be specified as follows:

path: /:infoPage(about-us|terms|privacy|contact|faqs)

/about-us, /terms, /privacy, /contact, /faqs

So far for Next.js, I thought I'd use a dynamic route as seen below. The only issue is that the URLs will now have /infoPage/___ - /infoPage/about-us, /infoPage/terms.

/pages
   /infoPage
      /[infoPage].js

As a solution links can be updated using as with the proper URL:

<Link href="/infoPage/[infoPage]?infoPage=about-us" as="/about-us">
   <a>About Us</a>
</Link>

Whilst this works when clicking on a link, refreshing the page will end up a 404 page - since Next.js is not aware of any page as /about-us.

Possible Solutions

I may be over thinking this, the second solution would not be the end of the world but I'm still wondering if there's a better solution.

Thanks in advance :)

Upvotes: 2

Views: 3803

Answers (1)

j.grima
j.grima

Reputation: 1941

In case someone is looking for an answer to this question, here are two solutions you may consider.

1. Dynamic Route in /pages at root level

Use Case: Pages using the same components with similar data (for example API call to get page content)

If you have certain pages similar to each other at root level, you can create a dynamic route such as below:

/pages
   /[rootPage].js

Keep in mind that if these pages are using Static Site Generation, slugs need to declared using getStaticPaths.

Further details on getStaticPaths here

It is also important to note that predefined routes take precedence over dynamic routes. Should a dynamic route have a slug the same as a predefined route, Next will always render the predefined route. So this approach can be risky at root level.

Dynamic Routing Caveats

2. Separate routes, one getStaticProps function

Use Case: Pages require similar data/API calls but use different components

You may opt to have routes for each page but use the same getStaticProps function.

Routes:

/pages
   /about-us.js
   /terms.js

getStaticProps helper function:

const getPageStaticProps = () => {
   return async (context) => {
      // generic logic here
   }
}

Page (about-us.js, terms.js):

// /pages/about-us.js
function AboutPage(props) {
   return <AboutComponent {...props} />
}

export const getStaticProps = getPageStaticProps()

---

// /pages/terms.js
function TermsPage(props) {
   return <TermsComponent {...props} />
}

export const getStaticProps = getPageStaticProps()

This can also be implemented using getServerSideProps.


I opted for the second solution as it felt safer and still benefitted from having code shared between different pages. Obviously there may be other solutions our there that can be used :)

Upvotes: 1

Related Questions