Routing in Nextjs: How routing works in Nextjs

Last updated : Jul 30, 2023 12:00 AM

Routing works differently in Next js compared to React js. Unlike React js, Next js routing works based on the file system concept. All the pages intended to be accessible as a route must reside in a special folder called pages.

In this tutorial, I will explain how Next js routing works with a downloadable project example. See the download option at the end of this tutorial.

Next js page route structure

Each Next js page is a React Component reside in the pages directory. Each component in the pages directory is associated with a route based on its file name. The pages directory can have sub-directories with React components in them. Each of those components gets its route based on its location directory structure.

Figure 1 : Nextjs static routing
Figure 1 : Nextjs static routing

In the above page structure, each component in the pages folder gets its route as below.

  • realestate.js -> /categories/realestate/realestate
  • indes.js -> /categories
  • tools.js -> /categories/tools/tools
  • automotive.js -> /categories/automotive/automotive
  • about.js -> /about
  • contact.js -> /contact
  • privacy.js -> /privacy

Note that any index.js components automatically become the default root for the folder. Every route will follow its domain name, for example, www.example.com/categories/realestate.

Also, note that each route has a repeated folder name and file name. That is because we are creating more files in those directories to show different dynamic route types. For static routing explained above, you can put all the category components inside the category folder without creating individual folders.

Next js Dynamic routes

What we have discussed so far is static routing. Meaning, the router pages don't accept any variables, neither path variables nor request variables. That's not very helpful when it comes to building dynamic web applications. I will discuss five different dynamic routes in Next js.

Figure 2 : Next js Dynamic routes
Figure 2 : Next js Dynamic routes

Next js page accepts path variable

Now, let's convert our automotive.js page to accept a path variable. All you need to do is to change the file name to [automotive].js It's a little unusual naming convention but still a valid file name. Now, /categories/automotive/[automotive].js is accisable via /categories/automotive/:variable For example, /categories/automotive/Cars and Suvs

Here is how you retrieve the variable value in the page component.

import React from 'react';
import TopMenu from '../../../components/TopMenu';
import { useRouter } from 'next/router'

function Posts({ posts }) {
  const router = useRouter()
  const { automotive } = router.query
  return (
     <>
        <TopMenu />
        <table>
           <tr>
              <th>[automotive].js Page</th>
           </tr>
           <tr>
              <td>You are searching for: {automotive}</td>
           </tr>
        </table>
     </>
  );
}
export async function getServerSideProps({ params }) {
    const users = [];
    return { props: { users } }
}
export default Posts;

Alternatively, if I rename the realestate directory to [realestate], the URL variable position will replace the placeholder. /categories/[realestate]/realestate.js is accisable via /categories/:variable/realestate

For example, /categories/New York/realestate

Here is how you retrieve the variable value in the page component.

import { useRouter } from 'next/router';
import React from 'react';
import TopMenu from '../../../components/TopMenu';

function Posts({ posts }) {
  const router = useRouter();
  const {realestate} = router.query;
  return (
     <>
        <TopMenu />
        <table>
           <tr>
              <th>Realestate</th>
           </tr>             
           <tr>
              <td>
                 <p>This is /categories/[realestate]/realestate.js page</p>
                 <p>This page has /categories/***/realestate url pattern</p>
                 <p>You are searching realestate in <b>{realestate}</b> area</p>
              </td>
           </tr>
        </table>
     </>
  );
}
   
export async function getServerSideProps({ params }) {
   const users = [];
   return { props: { users } }
}
export default Posts;

Another possibility is /categories/[realestate]/[realestate].js where [realestate].js page receives two path variables. This route is accessible via categories/New York/Two story url

Next js catch-all routes

Our simple dynamic route /categories/tools/[tools].js can be extended to catch all matching paths by prepending three dots to the component file name. The syntax follows as /categories/tools/[...tools].js. This route catches /categories/tools/New, /categories/tools/New/Two Story, /categories/tools/New/Two Story/Four Bedroom, etc... Note that the above route will not catch /categories/tools

import { useRouter } from 'next/router';
import React from 'react';
import TopMenu from '../../../components/TopMenu';

function Posts({ posts }) {
   const router = useRouter();
   const tools = router.query.tools || []
   return (
      <>
        <TopMenu />
        <table>
           <tr>
              <th>Tools</th>
           </tr>
           <tr>
              <td>
                 <p>This is /categories/tools/[...tools].js page</p>
                 <p>You are searching for Tools : {tools[0]}, {tools[1]}, {tools[2]}, and are {tools[3]}</p>
              </td>
           </tr>
        </table>
      </>
   );
}
export async function getServerSideProps({ params }) {
   const users = [];
   return { props: { users } }
}
export default Posts;

Next js Optional catch-all routes

The route /categories/search/[[...search]].js catches all the routes /categories/search/[...search].js does plus /categories/search. Examples are /categories/search/cars, /categories/search/cars/4 doors, /categories/search/cars/4 doors/3500cc etc... and /categories/search

import { useRouter } from 'next/router';
import React from 'react';
import TopMenu from '../../../components/TopMenu';

function Posts({ posts }) {
   const router = useRouter();
   const search = router.query.search || []
   return (
      <>
         <TopMenu />
         <table>
            <tr>
               <th>Tools</th>
            </tr>
            <tr>
               <td>
                  <p>This is /categories/search/[[]...search]].js page</p>
                  <p>You are searching for : {search[0]}, {search[1]}, {search[2]}</p>
               </td>
            </tr>
         </table>
      </>
   );
}
export async function getServerSideProps({ params }) {
    const users = [];
    return { props: { users } }
}
export default Posts;

Next js dynamic routing code download

Our fully functional downloadable code project includes a deployable working example of all possible routing scenarios.

  • /categories/[realestate]/realestate.js
  • /categories/automotive/[automotive].js
  • /categories/[realestate]/[realestate].js
  • /categories/tools/[...tools].js
  • /categories/search/[[...search]].js

Feel free to download and deploy it for a depth understanding of how Next js dynamic routing works.

Download Next js routing example project

Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...