DEV Community


Using Next.js Link Component with Material UI Buttons and Menu Items

Ivan V.
Full-stack web developer
・2 min read

Link component is a magic component of next.js framework, that does the routing both client-side and server-side (properly rendering links for SEO purposes).

Material UI is a most popular framework for implementing Google's material design system.
Since both frameworks expect a certain HTML structure to be present in order to render their components, using them together is not straightforward as it seems, luckily it's not that hard at all.

In this article, I'm going to show you how to properly render material UI buttons and menu items as nextjs links.

Rendering a material UI button is very easy, just wrap the button component with the nextjs link component and make sure you use passHref property on the link component.

<Link href="/about" passHref>
  <Button variant="contained" color="secondary">About</Button>
Enter fullscreen mode Exit fullscreen mode

passHref must be used every time you use a custom component inside the Link component. Without it when you test your code client side it will appear that everything is working because the Link component will properly route the links however the generated a tag will not have a href property, so website crawlers will see no links, which will negatively impact your SEO.
The reason it appears that it works is that the link component has a value for href and it just listens to click events on its child components and then does the routing.

You can confirm this by disabling javascript in the browser and trying to navigate nextjs app, you will see that the links won't work.

Using ListItem Component

ListItem component is used inside all kinds of material UI menus, and it is a little bit trickier to set up because the generated HTML structure of the component is more complex than a simple button component.

Outhere on the internet you will find a lot of solutions that are using higher-order components and passing props all over the place however, the solution is very simple and it is offered by the API of the ListItem component itself.
What we need to do is to change the underlying element of the ListItem component to be an a tag. We can do this by using the component property of the ListItem.

<Link href="/about" passHref>
 <ListItem button component="a" onClick={onClick}>
Enter fullscreen mode Exit fullscreen mode

And that's it, links will work on the client-side, and they will be properly rendered on the server-side.

Discussion (1)

fabarea profile image
Fabien Udriot

Very useful piece of information. Thanks.