Skip to content
+

Routing libraries

By default, the navigation is performed with a native <a> element. You can customize it, for instance, using Next.js's Link or react-router.

There are two main components available to perform navigations. The most common one is the Link as its name might suggest. It renders a native <a> element and applies the href as an attribute.

Link
Press Enter to start editing

You can also make a button perform navigation actions. If your component is extending ButtonBase, providing a href prop enables the link mode. For instance, with a Button component:

Link
Press Enter to start editing

In real-life applications, using a native <a> element is rarely enough. You can improve the user experience by using an enhanced Link component systematically. The Material UI theme lets you configure this component once. For instance, with react-router:

import { Link as RouterLink, LinkProps as RouterLinkProps } from 'react-router-dom';
import { LinkProps } from '@mui/material/Link';

const LinkBehavior = React.forwardRef<
  HTMLAnchorElement,
  Omit<RouterLinkProps, 'to'> & { href: RouterLinkProps['to'] }
>((props, ref) => {
  const { href, ...other } = props;
  // Map href (Material UI) -> to (react-router)
  return <RouterLink ref={ref} to={href} {...other} />;
});

const theme = createTheme({
  components: {
    MuiLink: {
      defaultProps: {
        component: LinkBehavior,
      } as LinkProps,
    },
    MuiButtonBase: {
      defaultProps: {
        LinkComponent: LinkBehavior,
      },
    },
  },
});

component prop

You can achieve the integration with third-party routing libraries with the component prop. You can learn more about this prop in the composition guide.

react-router examples

Here are a few demos with react-router. You can apply the same strategy with all the components: BottomNavigation, Card, etc.

Press Enter to start editing

Button

With prop forwarding
With inlining
Press Enter to start editing

Note: The button base component adds the role="button" attribute when it identifies the intent to render a button without a native <button> element. This can create issues when rendering a link. If you are not using one of the href, to, or component="a" props, you need to override the role attribute. The above demo achieves this by setting role={undefined} after the spread props.

const LinkBehavior = React.forwardRef((props, ref) => (
  <RouterLink ref={ref} to="/" {...props} role={undefined} />
));

Tabs

Current route: /drafts

InboxDraftsTrash

List

Current route: /drafts


More examples

Next.js Pages Router

The example folder provides an adapter for the use of Next.js's Link component with Material UI.

  • The first version of the adapter is the NextLinkComposed component. This component is unstyled and only responsible for handling the navigation. The prop href was renamed to to avoid a naming conflict. This is similar to react-router's Link component.

    import Button from '@mui/material/Button';
    import { NextLinkComposed } from '../src/Link';
    
    export default function Index() {
      return (
        <Button
          component={NextLinkComposed}
          to={{
            pathname: '/about',
            query: { name: 'test' },
          }}
        >
          Button link
        </Button>
      );
    }
    
  • The second version of the adapter is the Link component. This component is styled. It uses the Material UI Link component with NextLinkComposed.

    import Link from '../src/Link';
    
    export default function Index() {
      return (
        <Link
          href={{
            pathname: '/about',
            query: { name: 'test' },
          }}
        >
          Link
        </Link>
      );
    }
    
Edit this page

Was this page helpful?


CompositionServer rendering

Blog

Store