DEV Community

akfm
akfm

Posted on

Make Next.js internal links type-safe

Next.js is great, but I'm complaining that URL generation isn't type-safe.
So I created a library next-type-link-gen that can generate links in a type-safe way.

https://github.com/AkifumiSato/next-type-link-gen/tree/main

$ npm install next-type-link-gen
Enter fullscreen mode Exit fullscreen mode
import {
  dynamicRoute,
  nextLinksHooksFactory,
  staticRoute,
} from 'next-type-link-gen'

const useNextLinks = nextLinksHooksFactory({
  top: staticRoute('/'),
  name: dynamicRoute<{
    name: string
    a?: string
    b?: number
  }>('/[name]'),
})

const YourLink: React.FC = () => {
  const links = useNextLinks()

  return (
    <div>
      <Link
        // href: /
        href={links.top.toUrl()}
        // if `pathname` in next/router match, true
        current={links.top.isCurrent()}
      >
        Top
      </Link>
      <Link
        // href: /your_name?a=aaa&b=999
        href={links.name.toUrl({
          name: 'your_name',
          a: 'aaa',
          b: 999,
        })}
        // if `pathname` in next/router match, true
        current={links.name.isCurrent()}
      >
        User top
      </Link>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can also test to see if it meets the Next.js routing.

import { renderHook } from '@testing-library/react-hooks'
import { linksMapToRouteString, readNextPagesRoute } from 'next-type-link-gen/utils'
import { useNextLinks } from './url'

test('[useNextLinks] routes', () => {
  const { result } = renderHook(useNextLinks)

  const pageUrls = readNextPagesRoute()
  const routeUrls = linksMapToRouteString(result.current)

  expect(pageUrls).toEqual(expect.arrayContaining(routeUrls))
})
Enter fullscreen mode Exit fullscreen mode

If you find it difficult to use, please feel free to use Issue!
Thanks for reading.

Top comments (0)