Introduction to Next.js Link component
Tags: nextjs, react, webdev, programming
Published: 2022-09-05 11:59:16

---
canonical_url: https://refine.dev/blog/next-js-link-component
---


**Author: <a  target="_blank" href="https://refine.dev/blog/author/michael/">Michael Hungbo</a>**

## 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:

- [Introducing the `<Link/>` component](#introducing-the-link-component)
- [The Next.js Link component props](#the-link-component-props)
  - [Required props](#required-props)
  - [Optional props](#optional-props)

## 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](https://nextjs.org/docs) 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:

```tsx
import Link from 'next/link'

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

export default Home
```

## 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**

```javascript
<Link href="https://nextjs.org/docs"> Read the Docs </Link>
```

**Relative URL**

```javascript
<Link href="/about"> About Us </Link>
```

**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.

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

```
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:

```text
📦pages
 ┣ 📂api
 ┃ ┗ 📜hello.js
 ┣ 📂products
 ┃ ┣ 📜index.js
 ┃ ┗ 📜[product].js
 ┣ 📜index.js
 ┗ 📜_app.
 ```

 Next, add the following code to `pages/products/index.js`:
 
 ```tsx
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;
```

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

```tsx 
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
```

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


![product description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w12y6e0qqtor5sdrh07j.png)


<br/>

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/euu8mo1cygqvkpigu76i.gif)

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:

```diff 
  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;
```
Now if you navigate to `localhost:8000` a custom red link should be displayed like below: 


![Custom description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phbj212xwm41vnex3i7m.png)


### `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:


```tsx
<Link href='/products' prefetch={false}><a>Click me!</a></Link>
```

<br/>
<div>
<a href="https://github.com/pankod/refine">
  <img  src="https://refine.dev/img/github-support-banner.png" alt="github support banner" />
</a>
</div>

### `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:


```tsx 
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>
  );
}
```

The page should look like below:



![Home description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hnodrm9xg13khe3a6b3.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htrickflvchibnnio3c8.gif)

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

```diff
... 

{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>
      ))}
 ...
```

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



![Image replace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftpkyecbgbdpl9gok61t.gif)

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

```javascript
<Link href="/blog/intro" scroll={false}>
  <a>Disables scrolling to the top</a>
</Link>
```

#### Scroll to a specific section in a webpage using hash ids

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

### `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](https://nextjs.org/docs/advanced-features/i18n-routing).

### `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](https://nextjs.org/docs/api-reference/next/router#userouter) or [withRouter](https://nextjs.org/docs/api-reference/next/router#withrouter). 

[Here's](https://github.com/vercel/next.js/blob/canary/examples/with-shallow-routing/pages/index.js) 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](https://nextjs.org/docs/api-reference/next/link) for references and additional information.

** Writer: Michael Hungbo**

<br/>
<div>
<a href="https://discord.gg/refine">
  <img  src="https://refine.dev/img/discord-banner.png" alt="discord banner" />
</a>
</div>

---

## 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](https://github.com/pankod/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.


<div>
<a href="https://github.com/pankod/refine">
    <img  src="https://refine.dev/img/refine_blog_logo_1.png" alt="refine blog logo" />
</a>
</div>

<br/>

**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](https://github.com/pankod/refine) for more information, demos, tutorials, and example projects.