Introduction to Next.js Link component

necatiozmen

Necati Özmen

Posted on September 5, 2022

Introduction to Next.js Link component

Author: Michael Hungbo

Introduction

If you have built websites and applications on the web, then you're very likely to have used a common method for navigation. Traditionally, navigation is often achieved with the HTML anchor element (<a></a>). The anchor element is primarily used for navigating within and outside websites and webpages, and it serves its purpose pretty well.

In this article, we'll introduce you to Next.js <Link/> component, a similar method of navigation to the native anchor element but with additional built-in features for optimization. The Next.js Link component has additional benefits, such as options to customize navigation behavior through props and improved performance and SEO metrics.

Steps we'll cover:

Prerequisites

You'll need a good knowledge of writing and understanding code in JavaScript and React to grasp this article.

  • You'll also need a next.js project to get started. Visit here to see how to create a next.js app.
  • Next, run npm install styled-components in the terminal to install styled-components. We'll use it for styling in this tutorial.

Introducing the <Link/> component

The Link component provides a method of client-side navigation within Next.js applications. It's recommended over the native anchor tag because it has many built-in features that help improve application performance and SEO ranking. Some of these features include preloading page content and faster navigation since routing is handled with JavaScript.

In addition, client-side navigation with the Link component does not involve full page reloads, which is very significant in application performance and user experience.

The Link component is exported from the next/link core module. Here's a basic demo showing its usage:

import Link from 'next/link'

function Home () {
    return (
        <>
            <h1> Visit our About page</>
            <Link href="/about"> About Us </Link>
        </>
    )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

The Link component props

Required props

href

The Next.js Link component requires a single mandatory prop: href.

href specifies the path or URL to navigate to. This could be an absolute URL, a relative URL, or a URL object.

Absolute URL

<Link href="https://nextjs.org/docs"> Read the Docs </Link>
Enter fullscreen mode Exit fullscreen mode

Relative URL

<Link href="/about"> About Us </Link>
Enter fullscreen mode Exit fullscreen mode

URL objects

With a URL object, we can resolve URLs using strings and parameters passed as an object to the Next.js Link component. Here's a demo showing how to use it in the Link component.

<Link
    href={{
      pathname: '/products',
      query: { product: '1' },
    }}
>
    <a>Search for product 1</a>
</Link>

Enter fullscreen mode Exit fullscreen mode

The above example will resolve the href value into: /products/?product=1.

Optional props

as

The as prop is used with href when using dynamic routes. It specifies a link decorator, which provides additional information about a URL that can be used in analytics (such as ads and affiliate programs) and tracking webpage performance.

The decorator usually appears after a '?' in the URL of a webpage and does not change the destination of the URL. An example of a URL with link decoration is 'http://www.refine.com/blog/article?referrer_source=newsletter'.

Example

Create new folders and files in the pages folder of your application to look like below:

📦pages
 ┣ 📂api
 ┃ ┗ 📜hello.js
 ┣ 📂products
 ┃ ┣ 📜index.js
 ┃ ┗ 📜[product].js
 ┣ 📜index.js
 ┗ 📜_app.
Enter fullscreen mode Exit fullscreen mode

Next, add the following code to pages/products/index.js:

import React from "react";
import Link from "next/link";

const ProductsList = () => {
  const productIDs = ["1", "2", "3"];
  return (
    <>
      <div>
        <h1>Products List</h1>
      </div>

      {productIDs.map((product, key) => (
        <Link
          href="/products/[product]"
          as={`products/${product}/?referrer_source=newsletter`}
          key={key}
        >
          <a>
            <h1>{product}</h1>
            <p>Learn more about product {product}</p>
          </a>
        </Link>
      ))}
    </>
  );
};

export default ProductsList;
Enter fullscreen mode Exit fullscreen mode

And in pages/products/[product].js, add the following code:

import React from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'

const Product = () => {
    const router = useRouter();
    const productID = router.query.product;
    return (
        <>
            <h1>
            <Link href='/products'><a>Go back to Products</a></Link>
            </h1>
            <div>
                <h5>Product {productID} Details Page</h5>
            </div>
            </>
  )
}

export default Product
Enter fullscreen mode Exit fullscreen mode

If you navigate to localhost:3000/products you should see the page rendered like so:

product description

Now, if you click on any of the products, you'll be taken to the details page of each product which is a dynamic route.

example description

In the above demo we can see the URL of every product contains a link decorator, ?referrer_source=newsletter, which does not affect the link's destination.

passHref

The passHref prop forces the Next.js Link component to send the href prop to its child. This is important when the child of </Link> is a custom component that wraps an anchor tag (<a>).

Not adding the passHref prop in this scenario will hurt SEO and accessibility because the <a> tag will not have the href property. It is disabled by default.

Example

Edit the code in pages/products/index.js to the following:

  import React from "react";
  import Link from "next/link";
+ import styled from 'styled-components'


+ const CustomLink = styled.a`
+ color: red;
+ font-size: 30px;
+ `

const ProductsList = () => {
  const productIDs = ["1", "2", "3"];
  return (
    <>
      <div>
+        <NavLink href='/' name='Home'/>
        <h1>Products List</h1>
      </div>

      {productIDs.map((product, key) => (
        <Link
          href="/products/[product]"
          as={`products/${product}/?referrer_source=newsletter`}
          key={key}
        >
          <a>
            <h1>{product}</h1>
            <p>Learn more about product {product}</p>
          </a>
        </Link>
      ))}
    </>
  );
};

+ const NavLink = ({ href, name }) => {
+  return (
+    <Link href={href} passHref>
+      <CustomLink>{name}</CustomLink>
+    </Link>
+ )
+ };

export default ProductsList;
Enter fullscreen mode Exit fullscreen mode

Now if you navigate to localhost:8000 a custom red link should be displayed like below:

Custom description

prefetch

Preloading page content can drastically improve application performance. The prefetch prop allows the preloading of pages in the background and is enabled by default in the Next.js Link component. It only works in production, and if you wish to disable preloading, you can configure it like so:

<Link href='/products' prefetch={false}><a>Click me!</a></Link>
Enter fullscreen mode Exit fullscreen mode


github support banner

replace

The replace prop changes how navigation works by replacing the current history state instead of adding a new URL into the stack. This can be demonstrated by clicking on the back button in the navigation bar in the browser.

Edit the content in pages/index.js to the following:

import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import styles from "../styles/Home.module.css";

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>Introduction to next/link</h1>
        <h1>
          <Link href='/products'>Go to products page</Link>
        </h1>
      </main>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The page should look like below:

Home description

If you click on the Go to products page link, watch how the application navigation works when we click on the back navigation button without the replace prop in the GIF below.

image

Next, find the part that contains the code below in pages/products/index.js and add the replace prop to it like so:

... 

{productIDs.map((product, key) => (
        <Link
          href="/products/[product]"
          as={`products/${product}/?referrer_source=newsletter`}
          key={key}
+          replace={product === '3' ? true : false}
        >
          <a>
            <h1>{product}</h1>
            <p>Learn more about product {product}</p>
          </a>
        </Link>
      ))}
 ...
Enter fullscreen mode Exit fullscreen mode

Now let's go back to the browser and see how the navigation works with replace prop.

Image replace

As you can see in the GIF above, when we visited the product 3 details page and then clicked the back navigation button, instead of returning to the products page, we were taken to the home page instead.

scroll

Clicking on a link using the Link component will scroll to the top of the destination page by default. It's also possible to scroll to a specific section of the new page by using hash ids (the part of a URL after a #). You can disable the default behavior or hash ids by setting scroll={false} on the Link component.

Disable scroll to top

<Link href="/blog/intro" scroll={false}>
  <a>Disables scrolling to the top</a>
</Link>
Enter fullscreen mode Exit fullscreen mode

Scroll to a specific section in a webpage using hash ids

<Link href="https://refine.dev/blog/mui-datagrid-refine/#material-ui-datagrid-component">
  <a>Scroll to a specific section</a>
</Link>
Enter fullscreen mode Exit fullscreen mode

locale

The locale prop is used to navigate users to different versions of a webpage based on the user's preferred locale (language and region). For example, we may have a blog that is read by English and French users, and we need to render the blog content in English for English users and in French for French users.

We can serve English or French users different versions of our webpage in their preferred language by configuring the i18n object in next.config.js. Read more about configuring locales here.

shallow

The shallow props let us update the path of the current page without running any of Next.js data fetching methods (that is, getStaticProps, getServerSideProps or getInitialProps). The updated pathname and query associated with the new URL can be accessed by the router object provided by useRouter or withRouter.

Here's a good example showing how to use shallow routing in your web pages.

Conclusion

The Next.js Link component simplifies client-side navigation, and we recommend using it over the native anchor element for routing in your next.js applications. In this article, you learned how to use Link and configure its behavior using props to suit your use cases. You also learned how important concepts such as dynamic routes and URL objects work using the Link component.

We hope you found this article useful in getting started with next/link and client-side navigation in next.js. You can read the Next.js Link component docs here for references and additional information.

** Writer: Michael Hungbo**


discord banner


Build your React-based CRUD applications without constraints

Modern CRUD applications are required to consume data from many different sources from custom API’s to backend services like Supabase, Hasura, Airtable and Strapi.

Check out refine, if you are interested in a backend agnostic, headless framework which can connect 15+ data sources thanks to built-in providers and community plugins.


refine blog logo

refine is an open-source React-based framework for building CRUD applications without constraints.
It can speed up your development time up to 3X without compromising freedom on styling, customization and project workflow.

refine is headless by design and it connects 30+ backend services out-of-the-box including custom REST and GraphQL API’s.

Visit refine GitHub repository for more information, demos, tutorials, and example projects.

💖 💪 🙅 🚩
necatiozmen
Necati Özmen

Posted on September 5, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related