@stefanprobst/next-active-link
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

next-active-link

Replacement for Next.js's Link to inform child components whether the current route matches the link's href. Children can access this info with the useActiveLink hook.

By default, ActiveLink matches pathnames exactly, ignoring query params and hash. However, a custom matcher function can be provided.

ActiveLink

In addition to Next.js's LinkProps, ActiveLink accepts an optional matcher function as the isMatchingRoute prop, which receives the ActiveLink's href and as props, as well as the current route as arguments.

Note that ActiveLink inherits Next.js's Link behavior of accepting either a string, or an URL object for href and as props.

The following props are suitable for comparison:

current route LinkProps (as UrlObject, not string)
current.pathname href.pathname
new URL(current.asPath, 'https://example.org/').pathname (as ?? href).pathname
current.query href.query
new URL(current.asPath, 'https://example.org/').hash href.hash

Example:

import ActiveLink from '@stefanprobst/next-active-link'
import type { RouteMatcher } from '@stefanprobst/next-active-link'

/** dummy base url, since the URL constructor only handles absolute URLs */
const baseUrl = new URL('https://example.org/')

const isMatchingPathnameExactly: RouteMatcher = ({ current, as, href }) => {
  const to = as ?? href
  const link = typeof to === 'string' ? new URL(to, baseUrl) : to
  const route = new URL(current.asPath, baseUrl)
  return route.pathname === link.pathname
}

return (
  <ActiveLink href="/" isMatchingRoute={isMatchingPathnameExactly} passHref>
    <ActiveAnchor>Click me</ActiveAnchor>
  </ActiveLink>
)

useActiveLink

Must be nested inside an ActiveLink.

const isActive = useActiveLink()

Example

import { forwardRef } from 'react'
import type { ComponentPropsWithoutRef, Ref } from 'react'
import ActiveLink, { useActiveLink } from '@stefanprobst/next-active-link'

const ActiveAnchor = forwardRef(function ActiveAnchor(
  props: ComponentPropsWithoutRef<'a'>,
  ref: Ref<HTMLAnchorElement>,
) {
  const isActive = useActiveLink()
  return <a aria-current={isActive ? 'page' : undefined} ref={ref} {...props} />
})

function Page() {
  return (
    <ActiveLink href="/docs/[slug]" as="/docs/intro" passHref>
      <ActiveAnchor>Click me</ActiveAnchor>
    </ActiveLink>
  )
}

Readme

Keywords

none

Package Sidebar

Install

npm i @stefanprobst/next-active-link

Weekly Downloads

2

Version

1.0.1

License

MIT

Unpacked Size

24.6 kB

Total Files

10

Last publish

Collaborators

  • stefanprobst