useLink

Provides the behavior and accessibility implementation for a link component. A link allows a user to navigate to another page or resource within a web page or application.

installyarn add @react-aria/link
version3.2.0
usageimport {useLink} from '@react-aria/link'

API#


useLink( (props: AriaLinkOptions, , ref: RefObject<HTMLElement> )): LinkAria

Features#


Links can be created in HTML with the <a> element with an href attribute. However, if the link does not have an href, and is handled client side with JavaScript instead, it will not be exposed to assistive technology properly. useLink helps achieve accessible links with either native HTML elements or custom element types.

  • Support for mouse, touch, and keyboard interactions
  • Support for navigation links via <a> elements or custom element types via ARIA
  • Support for disabled links

Anatomy#


A link consists of a pressable area usually containing a textual label or an icon that users can click or tap to navigate to another page or resource. In addition, keyboard users may activate links using the Enter key.

useLink returns props to be spread onto the link element:

NameTypeDescription
linkPropsHTMLAttributes<HTMLElement>Props for the link element.
isPressedbooleanWhether the link is currently pressed.

If a visual label is not provided (e.g. an icon or image only link), then an aria-label or aria-labelledby prop must be passed to identify the link to assistive technology.

Example#


This example shows a basic link using a native <a> element.

function Link(props) {
  let ref = React.useRef();
  let {linkProps} = useLink(props, ref);

  return (
    <a
      {...linkProps}
      ref={ref}
      href={props.href}
      target={props.target}
      style={{color: 'var(--blue)'}}>
      {props.children}
    </a>
  );
}

<Link href="https://adobe.com" target="_blank">
  Adobe
</Link>
function Link(props) {
  let ref = React.useRef();
  let {linkProps} = useLink(props, ref);

  return (
    <a
      {...linkProps}
      ref={ref}
      href={props.href}
      target={props.target}
      style={{color: 'var(--blue)'}}>
      {props.children}
    </a>
  );
}

<Link href="https://adobe.com" target="_blank">
  Adobe
</Link>
function Link(props) {
  let ref = React.useRef();
  let {
    linkProps
  } = useLink(
    props,
    ref
  );

  return (
    <a
      {...linkProps}
      ref={ref}
      href={props.href}
      target={
        props.target
      }
      style={{
        color:
          'var(--blue)'
      }}>
      {props.children}
    </a>
  );
}

<Link
  href="https://adobe.com"
  target="_blank">
  Adobe
</Link>

This example shows a client handled link using press events. It sets elementType to span so that useLink returns the proper ARIA attributes to expose the element as a link to assistive technology.

In addition, this example shows usage of the isPressed value returned by useLink to properly style the links's active state. You could use the CSS :active pseudo class for this, but isPressed properly handles when the user drags their pointer off of the link, along with keyboard support and better touch screen support.

function Link(props) {
  let ref = React.useRef();
  let {linkProps, isPressed} = useLink({...props, elementType: 'span'}, ref);

  return (
    <span
      {...linkProps}
      ref={ref}
      style={{
        color: isPressed
          ? 'var(--blue)'
          : 'var(--spectrum-global-color-blue-700)',
        textDecoration: 'underline',
        cursor: 'pointer'
      }}>
      {props.children}
    </span>
  );
}

<Link onPress={() => alert('Pressed link')}>Adobe</Link>
function Link(props) {
  let ref = React.useRef();
  let {linkProps, isPressed} = useLink(
    {...props, elementType: 'span'},
    ref
  );

  return (
    <span
      {...linkProps}
      ref={ref}
      style={{
        color: isPressed
          ? 'var(--blue)'
          : 'var(--spectrum-global-color-blue-700)',
        textDecoration: 'underline',
        cursor: 'pointer'
      }}>
      {props.children}
    </span>
  );
}

<Link onPress={() => alert('Pressed link')}>Adobe</Link>
function Link(props) {
  let ref = React.useRef();
  let {
    linkProps,
    isPressed
  } = useLink(
    {
      ...props,
      elementType: 'span'
    },
    ref
  );

  return (
    <span
      {...linkProps}
      ref={ref}
      style={{
        color: isPressed
          ? 'var(--blue)'
          : 'var(--spectrum-global-color-blue-700)',
        textDecoration:
          'underline',
        cursor: 'pointer'
      }}>
      {props.children}
    </span>
  );
}

<Link
  onPress={() =>
    alert(
      'Pressed link'
    )
  }>
  Adobe
</Link>

A link can be disabled by passing the isDisabled property. This will work with both native link elements as well as client handled links. Native navigation will be disabled, and the onPress event will not be fired. The link will be exposed as disabled to assistive technology with ARIA.

function Link(props) {
  let ref = React.useRef();
  let {linkProps} = useLink(props, ref);

  return (
    <a
      {...linkProps}
      ref={ref}
      href={props.href}
      target={props.target}
      style={{
        color: props.isDisabled ? 'var(--gray)' : 'var(--blue)',
        cursor: props.isDisabled ? 'default' : 'pointer'
      }}>
      {props.children}
    </a>
  );
}

<Link href="https://adobe.com" target="_blank" isDisabled>
  Disabled link
</Link>
function Link(props) {
  let ref = React.useRef();
  let {linkProps} = useLink(props, ref);

  return (
    <a
      {...linkProps}
      ref={ref}
      href={props.href}
      target={props.target}
      style={{
        color: props.isDisabled
          ? 'var(--gray)'
          : 'var(--blue)',
        cursor: props.isDisabled ? 'default' : 'pointer'
      }}>
      {props.children}
    </a>
  );
}

<Link href="https://adobe.com" target="_blank" isDisabled>
  Disabled link
</Link>
function Link(props) {
  let ref = React.useRef();
  let {
    linkProps
  } = useLink(
    props,
    ref
  );

  return (
    <a
      {...linkProps}
      ref={ref}
      href={props.href}
      target={
        props.target
      }
      style={{
        color: props.isDisabled
          ? 'var(--gray)'
          : 'var(--blue)',
        cursor: props.isDisabled
          ? 'default'
          : 'pointer'
      }}>
      {props.children}
    </a>
  );
}

<Link
  href="https://adobe.com"
  target="_blank"
  isDisabled>
  Disabled link
</Link>