Next.js file-based routing works fine when we directly change the path in the browser’s address bar. However, usually that is not how we want users to navigate on our web application. Ideally, we want users to be able to click links on our web pages and navigate. To do so, we need to setup Next.js Routing using Link Component.

If you are just starting with routing in Next.js, please go through the post on Next.js file-based routing. That post will clarify the basic concepts of routing and approach Next.js follows for the same.

1 – Normal Routing Approach

Before we look at how Next.js supports routing using Link component, let us look at how we do it in normal JavaScript.

See below example:

function HomePage() {
    return(
        <div>
            <h1>Home Page</h1>
            <ul>
                <li>
                    <a href="/portfolio">Portfolio</a>
                </li>
                <li>
                    <a href="/about">About</a>
                </li>
            </ul>
        </div>
    )
}

export default HomePage;

Basically, in the above component, we use the standard a href to setup a list of navigation links. The href property takes a string value for the path.

Technically, this approach works fine. However, the problem is that whenever the user clicks a particular link, it will reload the entire application. A fresh request goes to the server and the page is returned. This wipes out the existing application state and the application status is reset.

Basically, this approach does not give the single page experience that we want to provide to the users. This is the reason that Next.js supports a different approach for handling navigation.

2 – Next.js Routing using Link Component

To get around the issue of reloading the entire application and losing any state, Next.js provides a special component Link.

Let us use it in the same example as above.

import Link from 'next/link';

function HomePage() {
    return(
        <div>
            <h1>Home Page</h1>
            <ul>
                <li>
                    <Link href="portfolio">Portfolio</Link>
                </li>
                <li>
                    <Link href="about">About</Link>
                </li>
            </ul>
        </div>
    )
}

export default HomePage;

We first import Link from next/link module. We don’t put it in curly braces since Link is the default export from the module.

After importing, we use Link just like a component in places where we were using a href. The Link component also receives the href prop that takes a string value as input. This is basically the route path.

If we start the application now using npm run dev and click on the navigation links, it should work fine. We would be able to navigate to the portfolio page and about page without sending any new HTTP request to the server. Also, the app status will not reset.

3 – Next.js Routing with Link for Nested Pages

We can also support nested pages using the Next.js Link component.

See below example:

import Link from 'next/link';

function PortfolioPage() {
    return (
        <div>
            <h1>The Portfolio Page</h1>
            <ul>
                <li>
                    <Link href="/portfolio/adam">Adam</Link>
                </li>
                <li>
                    <Link href="/portfolio/shaun">Shaun</Link>
                </li>
            </ul>
        </div>
    )
}

export default PortfolioPage;

As you can see, the only change here is the value of href that now contains the complete path.

The portfolio component that can support this path is within the portfolio folder in a file named […slug].js

See below:

import { useRouter } from 'next/router';

function PortfolioByName() {
   const router = useRouter();

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

   return(
       <div>
           <h1>The Portfolio by Name Page</h1>
       </div>
   ) 
}

export default PortfolioByName;

Here, we are using Next.js dynamic routes using the useRouter hook.

4 – Next.js Routing for Dynamic Links

Many times, we don’t exactly know how many links are needed. In the portfolio example, the list of developers might be coming from some backend call and we have to create links for each developer.

In such a case, we can also render the Next.js Link routes in a dynamic manner. See below example:

import Link from 'next/link';

function PortfolioPage() {
    const developers = [
        { id: 'adam', name: 'Portfolio of Adam' },
        { id: 'shaun', name: 'Portfolio of Shaun' }
    ]
    return (
        <div>
            <h1>The Portfolio Page</h1>
            <ul>
                {
                    developers.map(developer => <li key={developer.id}>
                        <Link href={`/portfolio/${developer.id}`}>{developer.name}</Link>
                    </li>)
                }
            </ul>
        </div>
    )
}

export default PortfolioPage;

Here, we have a list of developers in an array. Each developer has an id and name property. Within the JSX, we loop through the developers array and render the Link component for each item in the array.

As the number of developers in the list changes, the number of links rendered will also change accordingly. Note that in the above example, we use template string to actually construct the path in the href prop.

5 – Next.js Link Href as Object

While supplying the href in the form of string is the easiest approach, we can also provide href value in the form of an object.

import Link from 'next/link';

function PortfolioPage() {
    const developers = [
        { id: 'adam', name: 'Portfolio of Adam' },
        { id: 'shaun', name: 'Portfolio of Shaun' }
    ]
    return (
        <div>
            <h1>The Portfolio Page</h1>
            <ul>
                {
                    developers.map(developer => <li key={developer.id}>
                        <Link href={{
                            pathname: "/portfolio/[id]",
                            query: {id: developer.id}
                        }}>{developer.name}</Link>
                    </li>)
                }
            </ul>
        </div>
    )
}

export default PortfolioPage;

Here, the href takes an object with a couple of properties. The pathname is the route path that we want to navigate to. It contains the dynamic id in square braces. Then, in the query property of the object, we provide the source for the id value.

This approach shines when the pathname string is too complex to build using template string. Otherwise, the string approach seems a bit more readable.

6 – Next.js Link Routing Programmatic Approach

Another approach is to change routes programmatically. Next.js link routing also supports programmatic approach. However, in this case, we need to utilize the useRouter() hook.

const router = useRouter();

router.push('portfolio/adam');

We are using the push() method available on the router object to change the route programmatically. The method takes the path name as string.

Also, we can use an object instead of the string the way we used in href. Depending on the need, we can choose the appropriate option.

Conclusion

Next.js Routing with Link component is a fantastic way to build complex navigation links in our application. By working within the application context, it stops a new HTTP request every time user navigates to a new page. This prevents the application state from getting lost.

Want to build a really big NextJS application? Check out this post to build a NextJS Event Management application.

If you have any comments or queries about this post, please feel free to mention them in the comments section below.

Categories: NextJS

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *