Next to React!

Part 1 – Pages and File based Routing

Pages and File based Routing

In this section we will cover the following:

  1. Understanding File-based Routing
  2. Static and Dynamic Routes
  3. Navigating Between Pages

What is file based routing?

In traditional reactjs, we use react-router-dom to establish routing as follows:

Now this is not a wrong approach, but with NextJS we don’t necessarily write such jsx code to establish routing.

The way to create routing in NextJS is by creating React component files and letting NextJs infer the routes from the folder structure.

This is done specially through the pages folder.

E.g.

We can see that the actual folder structure is used to establish the URL path of the page above.

To create a dynamic route, i.e. something like a products page with different ids, we simply follow the convention of having the id page within square brackets as:

[projectid].js

The above tells NextJs that projectid is dynamic and there shouldn’t be a fixed route such as:

mydomain.com/projectid but a dynamic route like mydomain.com/1 or mydomain.com/2 etc.

How to access dynamic routes?

To access dynamic routes in NextJs, it provides us with special hooks to use with this functionality.

We can import the useRouter as follows:

Import {useRouter} from ‘next/router;

We can then create an object to hold values of the hook and use the keys pathname and query to get more info from the routed path as follows:

  const router = useRouter();

  console.log(router.pathname);
  console.log(router.query);

The first key, i.e router.pathname gives us the way nextJS has inferred the routed path, however the second key, i.e. router.query gives us the actual parameter being passed into the dynamic url path.

One variation of above mentioned dynamic paths could be nested dynamic paths like,

mydomain.com/projects/1/2/

 Here there are 2 dynamic paths after the static path of projects

This behaviour can be replicated easily by doing a chain of dynamic routing.

I.e for the first dynamic path, we create a folder in nextJs directory structure with the similar syntax as seen before for a file:

This can be something like [id]

Notice we do not add .js  extension after this which signifies that this is a folder.

Within this folder, we can now create more nested dynamic paths such as [clientprojectid].js for a dynamic component to render our url.

An example of nested dynamic paths in NextJS is shown below:

Th

As seen by adding the same router.query log, now the log shows two dynamic parameters as id and clientprojectid.

Supporting multiple/all url formats in routes

There can be a scenario where we would be interested in getting all forms of url paths after a dynamic path.

This can be done using Catch-All routes of the nextJs

All we need to do is to modify our nextJs file structure again to include a spread operator before the file name.

E.g. 

Here we can see that […slug].js is the file that signifies the catch-all Routes.

If we use useRouter here, then we can see the following response for an example like:

http://localhost:3000/blog/1/2

Here we can see that the router gave us now an array of all the routes that come after the blog file.

NextJs gives us the linking functionality in two forms.

  1. We can simply use anchor tags and then provide the entire path in href to create our page links.
  2. Link component based routing.

The disadvantage to the first method is that it creates a new http request to run the link. This means that any state running up until that point shall be lost.

This basically means that we are rendering a brand new HTML page and hence any state by either react context or Redux shall be lost.

The second approach uses the Link component which is a default export from next/link as:

import React from ‘react’
import Link from ‘next/link’

function IndexPage() {
return (
  <div>
    Hello
    <ul>
      <li>
        <Link href=”/about”>About</Link>
      </li>
    </ul>
  </div>
)
}

export default IndexPage

In this example, we can see that Link works quite similar to the anchor tag, it just needs to be imported first in the component.

Link will also do some advanced optimisations like pre-fetching the data of the page to be loaded as soon as the Link is hovered in the web page.

This also removes the request concept and hence preserves the state of the page.

We can use the ‘replace’ props on Link to prevent user from going back to the previous page.

To navigate to dynamic routes like client/1 or client/2 all we need to do is create a similar Link and mention the dynamic route path:

A simple example of building dynamic links can be as follows:

import React from ‘react’

import Link from ‘next/link’

function ClientsPage() {
  const clients=[
      {id:“ak”,name:“sh”},
      {id:“pk”,name:“MJ”},

  ];
    return (
      <div>
          <h1>ClientsPage</h1>
          <ul>
               {clients.map((client) =><li key={client.id}>
                  <Link href={`/client/${client.id}`}>{client.name}</Link>

              </li>)}
          </ul>
      </div>
  )
}

export default ClientsPage

Above we can see that the links are generated from a clients array using the map function.

Instead of using String, we can also use an object to render dynamic routes as follows:

import React from ‘react’

import Link from ‘next/link’

function ClientsPage() {
  const clients=[
      {id:”ak”,name:”sh”},
      {id:”pk”,name:”MJ”},

  ];
    return (
      <div>
          <h1>ClientsPage</h1>
          <ul>
              {clients.map((client) =><li key={client.id}>
                  <Link href={{
                      pathname:“/client/[id]”,
                      query:{id:client.id}
                  }}>{client.name}</Link>

              </li>)}
          </ul>
      </div>
  )
}

export default ClientsPage

Here we can see that a Link object is used to build the routes. The format for routes is as:

{
pathname: “/path/[dynamic_path]/path”,
query: {<query on which path need>}

}

To navigate programmatically, e.g. when a button is clicked you want to move to a new page, this can be done easily as follows:

import React from ‘react’

import Link from ‘next/link’
import router from ‘next/router’;

function ClientsPage() {
  const clients=[
      {id:”ak”,name:”sh”},
      {id:”pk”,name:”MJ”},

  ];

  const loadProjectHandler=()=>{
      router.push(“/client/ak/projectA”);
  }
    return (
      <div>
          <h1>ClientsPage</h1>
          <ul>
              {clients.map((client) =><li key={client.id}>
                  <Link href={{
                      pathname:”/client/[id]”,
                      query:{id:client.id}
                  }}>{client.name}</Link>

              </li>)}
          </ul>

           <button onClick={loadProjectHandler}>Load Project A</button>
      </div>
  )
}

export default ClientsPage

When handling navigation programmatically, it is better to use the router object.

We can use router.push(<path to route>) to route the user to the desired page programmatically.

If we want to stop the user from moving back the route, we can use router.replace(<path to route>) to achieve this.

Other than that, we can also use the same object query notation as we used in Link to create a programmatic route path inside the router.push or router.replace function.

Adding Custom 404 pages

NextJs makes it very easy to add 404 pages.

All we need to do is add a 404.js page in the base or root of the pages folder.

Then we can work on it as a simple react component.

E.g.

We can see the 404.js page added to the root of pages folder.

Summary

We can summarise the File-based v/s Code-based routing as follows:


So that is it for this week’s dose of NextJs! I hope you learnt how NextJs can be your saviour from ReactJs’ complex routing setup. This really works in the developer’s favour as it reduces dev time and improves project management.

I truly am excited to share these posts on NextJs as I myself keep on diving deep and exploring how NextJs is the next big thing in development.


Follow this fortnightly series on NextJs – Next to React! and the ongoing Learning CSS series to truly help you transform your skills to the next level!

If you haven’t checked out the Learning CSS Series, begin here!

Checkout my React Bullets- Book1 on Amazon to begin with ReactJs today!



If you wish to learn more about CSS, checkout my book “CSS Bullets, a comprehensive guide to all the CSS you need!”.

Thanks for sticking around!

Hope you like this series and stay tuned for more content on the learning.

Leave a Reply

Discover more from The CodeWolf

Subscribe now to keep reading and get access to the full archive.

Continue reading