72

The following messes with the onClick animation (the ListItem turns red):

<List>
  <a href="https://www.google.com">
    <ListItem button>
       <ListItemText primary="Google" />
     </ListItem>
   </a>
 </List>

While adding the link inside ListItem, only makes the transition work if ListItemText is clicked, which is not what I want. What is the correct way to add a link?

JiiB
  • 1,432
  • 1
  • 12
  • 26
Luis F.
  • 1,222
  • 1
  • 11
  • 12

8 Answers8

174

to use with "react-router-dom"

import { Link } from "react-router-dom";
<ListItem button component={Link} to="/design">

the example is based in this section: docs

Julian Botia
  • 1,871
  • 2
  • 10
  • 9
  • 4
    This is a good solution if you need to rely on Push-State URLs. – cheersjosh May 30 '18 at 05:55
  • 3
    This should be the correct solution effective to the latest version of Material UI – ukalpa Feb 22 '19 at 01:05
  • What if I need some part of the list item to routable but not the whole thing? In my scenario I have some text that I want to be clickable, and then an exand chevron to view sections beneath that one – Crhistian Ramirez Jul 10 '19 at 14:26
  • I don't really understand how this works; What does it technically mean if I add Link as a component property? – Jordec Nov 06 '19 at 12:56
  • 2
    With Material UI 4.11.0, this solution doesn't work, at least for me. Getting " Property 'component' does not exist on type 'IntrinsicAttributes & { button: true; } & { alignItems?: "center" | "flex-start" | undefined; autoFocus?: boolean | undefined; button?: boolean | undefined; ... 7 more ...; selected?: boolean | undefined; } & { ...; } & CommonProps<...> & Pick<...>'" – Pedro Silva Oct 11 '20 at 15:26
  • does this work for external links? seems it only routes internally! – Mohamed Daher Nov 03 '20 at 16:47
  • Make sure to use `Link` from "react-router-dom" and not the MUI Component. – Joel Bourbonnais Mar 12 '21 at 13:53
95

The easiest way to accomplish this is to make the ListItem a link by using the component prop:

<List>
  <ListItem button component="a" href="https://www.google.com">
    <ListItemText primary="Google" />
  </ListItem>
</List>

That way, the ListItem will be an anchor tag linking to the desired place, but still receive the appropriate styling so that there won't be any visual changes.

The behavior of the component prop is documented here. Note that the href prop will be automatically passed to the anchor tag, as specified by the last line in the props documentation:

Any other properties supplied will be spread to the root element.

Jules Dupont
  • 7,259
  • 7
  • 39
  • 39
  • 5
    A `ListItem` with `component="a"` and `href` works great for external links. For internal links it's better to use `component={Link}` with a `to` attribute. – Benny Code Mar 03 '21 at 22:57
  • Extending @BennyNeugebauer answer if `href` is used it will reload the page so it shouldn't be used for some internal routes. – Shadab Jul 28 '21 at 12:12
4

I have faced the same issue but maybe a new update in materialUI due to this is not working, There has some tweak as import from import Link from '@material-ui/core/Link';

so it will works

 import Link from '@material-ui/core/Link';

 <List>
  <ListItem button component={Link} href="/dsda">
    <ListItemIcon>
      <DashboardIcon />
    </ListItemIcon>
    <ListItemText primary="DashBoard"/>
  </ListItem>
 </List>

Render Link in material ui Drawer

Mahesh More
  • 151
  • 7
4

For usage with Next.js, this worked for me:

import Link from "next/link";

<List>
    <Link href="/myUrl" passHref>
        <ListItem button component="a">
            My Link Text
        </ListItem>
    </Link>
</List>
Ian H.
  • 3,840
  • 4
  • 30
  • 60
3

For mui V5 + NextJS and if you want to have multiple children inside the list item (for example text and an icon) this worked for me:

import {
  Link,
  ListItem,
  ListItemIcon,
  ListItemText,
} from '@mui/material';
import NextLink from 'next/link';

<NextLink href="/some/route" passHref>
  <ListItem
    button
    component={Link}
  >
    <ListItemIcon>
      <SupportIcon />
    </ListItemIcon>
    <ListItemText
      primary="Support"
      secondary="Get super friendly support"
    ></ListItemText>
  </ListItem>
</NextLink>

This will give you real a-tags that still have nextjs-routing without page reloads.

Felix Hagspiel
  • 2,634
  • 2
  • 30
  • 43
2

ListItem's button prop is now DEPRECATED as you can see in ListItem props (MUI API Docs)

This would be the updated version of the code proposed by @JulesDupont answer:

<List>
  <ListItem>
    <ListItemButton component="a" href="https://www.google.com">
      <ListItemText primary="Google" />
    </ListItemButton>
  </ListItem>
</List>
1
import React, { forwardRef } from "react";
// material-ui components
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
// react-router
import { Link as RouterLink } from "react-router-dom";
const ListItemLink = (props) => {
  const { icon, primary, to } = props;

  const renderLink = React.useMemo(
    () =>
      forwardRef((itemProps, ref) => (
        <RouterLink to={to} ref={ref} {...itemProps} />
      )),
    [to]
  );

  return (
    <>
      <ListItem button component={renderLink}>
        {icon ? <ListItemIcon>{icon}</ListItemIcon> : null}
        <ListItemText primary={primary} />
      </ListItem>
    </>
  );
};

export default ListItemLink;

It's actually available in the docs.

Safwat Fathi
  • 758
  • 9
  • 16
0
    <Link to="/categories">
          <ListItem key={index} disablePadding sx={{ display: "block" }}>
            <ListItemButton
            >
              
              <ListItemText
              />
            </ListItemButton>
          </ListItem>
        </Link>
imjoymhnt
  • 1,011
  • 11
  • 14