Implementing ActiveLink in Next.js and Chakra
Tags: chakraui, javascript, reactrouter, createreactapp
Published: 2021-06-15 12:29:43

---
title: Implementing ActiveLink in Next.js and Chakra
published: true
description: How to implement an Navlink for Chakra and Next.js the easy
tags: chakraui, javascript,reactrouter, createreactapp
//cover_image: https://direct_url_to_image.jpg
---

I love Next.js, its speed, simplicity, tooling but one thing I hate about Next.js is its lack of a native active link component. Before Next.js, I was using create-react-app and react-router for most of my personal projects but once I switched over to Next.js one of my biggest pain point is that I have to pretty much write my own NavLink component every single time for every new project I made. There are a couple of tutorials and Stackoverflows on how to exactly solve this problem but none of them actually achieves the simplicity react-router offers out fo the box. 

In react-router when you want to make use of an active link all you do is import the nav-link component and pass it an `activeClassName` prop and voila it works. Just like this:

```tsx
<NavLink activeClassName='is-active' to='/about'>About</NavLink>
```

Most of tutorials on how to implement the ActiveLink api looks like this

```tsx
// adapted from https://stackoverflow.com/questions/53262263/target-active-link-when-the-route-is-active-in-next-js
import { useRouter } from 'next/router'
import PropTypes from 'prop-types'
import Link from 'next/link'
import React, { Children } from 'react'

const ActiveLink = ({ children, activeClassName, ...props }) => {
  const { asPath } = useRouter()
  const child = Children.only(children)
  const childClassName = child.props.className || ''

  const className =
    asPath === props.href || asPath === props.as
      ? `${childClassName} ${activeClassName}`.trim()
      : childClassName

  return (
    <Link {...props}>
      {React.cloneElement(child, {
        className: className || null,
      })}
    </Link>
  )
}

export default ActiveLink
```

The only issue with this API is that, it still acts like the normal Next.js link component which requires you to implement a link tag(<a></a>) as the child of the link component. But what if you are not using a library like ChakraUI. The implementation in Chakra looks like this:

```tsx
import { Link as ChakraLink, LinkProps, useColorModeValue } from '@chakra-ui/react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import React from 'react'

interface NavLinkProps extends LinkProps {
  children?: string | React.ReactNode
  to: string
  activeProps?: LinkProps
  _hover?: LinkProps
}

function NavLink({ to, activeProps, children, _hover, ...props }: NavLinkProps) {
  const router = useRouter()
  const isActive = router.pathname === to
  const color = useColorModeValue('black', 'selected')

  if (isActive) {
    return (
      <Link href={to}>
        <ChakraLink
          fontWeight='bold'
          {...props}
          {...activeProps}
          _hover={{ color: 'selected' }}
          color={color}>
          {children}
        </ChakraLink>
      </Link>
    )
  }

  return (
    <Link href={to}>
      <ChakraLink {...props} _hover={{ color: 'selected' }}>
        {children}
      </ChakraLink>
    </Link>
  )
}

export default NavLink
```

And to use it:

```jsx

<NavLink mr={4} to='/dashboard'>
   Dashboard
</NavLink>

<NavLink mr={4} to='/dashboard' activeProps={{fontWeight:'bold'}}>
    Dashboard
 </NavLink>
```