Skip to contents
This page is an adaptation of the related MUI Material UI documentation page.

The Link component allows you to easily customize anchor elements with your theme colors and typography styles.

The Link component is built on top of the Typography component, meaning that you can use its props. As in the MUI documentation, the demos prevent the navigation with an onClick handler on the wrapper.

preventDefault <- JS("(event) => event.preventDefault()")

muiMaterialPage(
  CssBaseline(),
  Box(
    sx = list(typography = "body1", "& > :not(style) ~ :not(style)" = list(ml = 2)),
    onClick = preventDefault,
    Link(href = "#", "Link"),
    Link(href = "#", color = "inherit", 'color="inherit"'),
    Link(href = "#", variant = "body2", 'variant="body2"')
  )
)
JS code
import * as React from 'react';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';

const preventDefault = (event) => event.preventDefault();

export default function Links() {
  return (
    <Box
      sx={{
        typography: 'body1',
        '& > :not(style) ~ :not(style)': {
          ml: 2,
        },
      }}
      onClick={preventDefault}
    >
      <Link href="#">Link</Link>
      <Link href="#" color="inherit">
        {'color="inherit"'}
      </Link>
      <Link href="#" variant="body2">
        {'variant="body2"'}
      </Link>
    </Box>
  );
}

However, the Link component has some different default props than the Typography component:

  • color = "primary" as the link needs to stand out.
  • variant = "inherit" as the link will, most of the time, be used as a child of a Typography component.

Underline

The underline prop can be used to set the underline behavior. The default is always.

muiMaterialPage(
  CssBaseline(),
  Box(
    sx = list(
      display = "flex", flexWrap = "wrap", justifyContent = "center", typography = "body1",
      "& > :not(style) ~ :not(style)" = list(ml = 2)
    ),
    onClick = preventDefault,
    Link(href = "#", underline = "none", 'underline="none"'),
    Link(href = "#", underline = "hover", 'underline="hover"'),
    Link(href = "#", underline = "always", 'underline="always"')
  )
)
JS code
import * as React from 'react';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';

const preventDefault = (event) => event.preventDefault();

export default function UnderlineLink() {
  return (
    <Box
      sx={{
        display: 'flex',
        flexWrap: 'wrap',
        justifyContent: 'center',
        typography: 'body1',
        '& > :not(style) ~ :not(style)': {
          ml: 2,
        },
      }}
      onClick={preventDefault}
    >
      <Link href="#" underline="none">
        {'underline="none"'}
      </Link>
      <Link href="#" underline="hover">
        {'underline="hover"'}
      </Link>
      <Link href="#" underline="always">
        {'underline="always"'}
      </Link>
    </Box>
  );
}

Third-party routing library

One frequent use case is to perform navigation on the client only, without an HTTP round-trip to the server. With a hash router such as createHashRouter() of reactRouter, a regular href that starts with #/ is enough: Link(href = "#/about", "About") navigates to the about route. See Using a router.

reactRouter also exports a Link() function, for its own links. When both packages are attached, the last one attached masks the other: call muiMaterial::Link() explicitly, or attach muiMaterial after reactRouter.

Accessibility

(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/link/)

  • When providing the content for the link, avoid generic descriptions like “click here” or “go to”. Instead, use specific descriptions.
  • For the best user experience, links should stand out from the text on the page. For instance, you can keep the default underline = "always" behavior.
  • If a link doesn’t have a meaningful href, it should be rendered using a <button> element. The demo below illustrates how to properly link with a <button>:
muiMaterialPage(
  CssBaseline(),
  Link(component = "button", variant = "body2", onClick = JS("() => { console.info(\"I'm a button.\"); }"), "Button Link")
)
JS code
import Link from '@mui/material/Link';

export default function ButtonLink() {
  return (
    <Link
      component="button"
      variant="body2"
      onClick={() => {
        console.info("I'm a button.");
      }}
    >
      Button Link
    </Link>
  );
}

In a Shiny app, send the click to the server with onClick = triggerEvent("link_clicked").

Keyboard accessibility

  • Interactive elements should receive focus in a coherent order when the user presses the Tab key.
  • Users should be able to open a link by pressing Enter.

Screen reader accessibility

  • When a link receives focus, screen readers should announce a descriptive link name. If the link opens in a new window or browser tab, add an aria-label to inform screen reader users, for example, “To learn more, visit the About page which opens in a new window.”