Picture of Bharathi Kannan

Bharathi Kannan

How to use Nextjs Link with Chakra UI

A closer photograph of chain connection

Photo ByEdge2Edge Media

One of the frequently asked questions on chakra ui library discussions is, How do I use nextjs link with chakra ui button or chakra link? In this post let us explore some common patterns to use nextjs link with chakra.

NextJS provides a Link component out of the box, that can be used for Client-side transitions between different routes. This Link component is exported from next/link package.

What is so special about this component is, it prefetches the linked route by default to provide rapid fast 🚀 page transitions. Until the Link becomes visible to the user, it won't prefetch the route, and once the Link is visible the prefetch is done in the background.

So, to use this component with our design system, we can create a custom component wrapper and make it reusable across the application. Let's see how to do that next.

Create Chakra Button with Next Link

Surround chakra Button with next's Link and provide a passHref prop so that it forwards href to the rendered anchor tag for proper semantics and SEO.

1import Link from "next/link";
2import { Button } from "@chakra-ui/react";
4function ChakraNextLinkButton({ href, children, ...props }) {
5 return (
6 <Link href={href} passHref>
7 <Button as="a" {...props}>
8 {children}
9 </Button>
10 </Link>
11 );
14function IndexPage() {
15 return (
16 <ChakraNextLinkButton href="/about" colorScheme="facebook">
17 About
18 </ChakraNextLinkButton>
19 );

Notice the as prop in chakra button on line number 7. We are rendering anchor tag instead of button on DOM and applying chakra button styles to it! You can pass all the chakra button props to the component ChakraNextLinkButton like onClick, padding, margin etc.

With this approach, we are following proper web semantics.

We can change the variant prop to 'link' to the same component to render the link styles.

1<ChakraNextLinkButton href="/about" variant="link">
2 About

At the same time, if you want to have control over next's Link via props, you would need to separate the props in the custom component and pass it appropriately like below

1import Link from "next/link";
2import { Button } from "@chakra-ui/react";
4function ChakraNextLinkButton({ href, children, prefetch = true, ...props }) {
5 return (
6 <Link href={href} passHref prefetch={prefetch}>
7 <Button as="a" {...props}>
8 {children}
9 </Button>
10 </Link>
11 );
14function IndexPage() {
15 return (
16 <ChakraNextLinkButton
17 href="/about"
18 colorScheme="facebook"
19 prefetch={false}>
20 About without prefetch
21 </ChakraNextLinkButton>
22 );

See more about Next's Link props in next's documentation about Link component

Create Chakra Link with Next Link

If we want to use Chakra's Link with Next's Link, we can do that easily by this method.

1import Link from "next/link";
2import { Link as ChakraLink } from "@chakra-ui/react";
4function ChakraNextLink({ href, children, ...props }) {
5 return (
6 <Link href={href} passHref>
7 <ChakraLink {...props}>{children}</ChakraLink>
8 </Link>
9 );
12function IndexPage() {
13 return (
14 <ChakraNextLink href="https://bharathikannan.com" isExternal color="red">
15 Visit my homepage
16 </ChakraNextLink>
17 )

Notice that we can pass isExternal prop to the custom component, and that would forward the prop to Chakra's Link component to add the target="_blank" and rel="noopener noreferrer" attributes to rendered HTML automatically.

Usage with Typescript

If you are using next js with typescript and if you want to make use of typescript intellisense, code completion and static type checking for our custom chakra components, you can create a new prop type by merging Chakra's Props and Next's Props and provide it to our component like below

1import Link, { LinkProps } from "next/link";
2import {
3 Button,
4 ButtonProps,
5} from "@chakra-ui/react";
7type ChakraAndNextProps = ButtonProps & LinkProps;
9function ChakraNextLinkButton({
10 href,
11 children,
12 prefetch = true,
13 ...props
14}: ChakraAndNextProps) {
15 return (
16 <Link href={href} passHref prefetch={prefetch}>
17 <Button as="a" {...props}>
18 {children}
19 </Button>
20 </Link>
21 );
24function IndexPage() {
25 return (
26 <ChakraNextLinkButton href="/about" colorScheme="facebook">
27 About
28 </ChakraNextLinkButton>
29 );

Wow! Now we got code completion with static props checking!

And for the Chakra Link,

1import Link, { LinkProps } from "next/link";
2import {
3 Link as ChakraLink,
4 LinkProps as ChakraLinkProps,
5} from "@chakra-ui/react";
7type ChakraLinkAndNextProps = ChakraLinkProps & LinkProps;
9function ChakraNextLink({ href, children, ...props }: ChakraLinkAndNextProps) {
10 return (
11 <Link href={href} passHref>
12 <ChakraLink {...props}>{children}</ChakraLink>
13 </Link>
14 );
18function IndexPage() {
19 return (
20 <ChakraNextLink href="https://bharathikannan.com" isExternal color="red">
21 Visit my homepage
22 </ChakraNextLink>
23 );

Great! Now we won't be missing Chakra's prop intellisense!

Note: In the above examples, you are responsible for separating chakra props and next props and passing it to the corresponding components!

Bonus Tip

You can shorten the prop spreading on components without mentioning children

2function ChakraNextLinkButton({ href, children, prefetch = true, ...props }) {
3 return (
4 <Link href={href} passHref prefetch={prefetch}>
5 <Button as="a" {...props}>
6 {children}
7 </Button>
8 </Link>
9 );
12// AFTER
13function ChakraNextLinkButton({ href, prefetch = true, ...props }) {
14 return (
15 <Link href={href} passHref prefetch={prefetch}>
16 <Button as="a" {...props} />
17 </Link>
18 );

Sandbox Links

Here is the sandbox link for all the above examples to see it live ✅

Do you think anything else to be added? Did you notice any issues in the post? Let me know at my Twitter handle, or please feel free to submit a PR to edit this post! There should be an Edit this Post link below 😀


Let's Discuss On TwitterTwitter
GitHubEdit this Post On GitHub
Open Twitter Profile of Bharathi KannanOpen LinkedIn Profile of Bharathi Kannan
❤️Open sourced on Github❤️