Skip to content

marcvangend/nextjs-block-link

Repository files navigation

nextjs-block-link

An accessible block link component for Next.js.

NPM

About Next.js Block Link

Some designs call for a block (sometimes called "card") that is linked as a whole. Technically is it possible to wrap the entire block in <a href>. However, doing so is terrible for accessibility because screenreaders will read the entire card when tabbing through the page.

This component makes it easy to create clickable blocks with accessibility in mind, using next/router for client-side transitions.

For more about accessible cards, read Inclusive Components: Cards and Block Links Are a Pain (and Maybe Just a Bad Idea).

Install

yarn add nextjs-block-link

-or-

npm install nextjs-block-link

Usage

Basic example

import Link from "next/link";
import { BlockLink } from 'nextjs-block-link'

const Card = () => {
  return (
    <BlockLink>
      <h2>
        <Link href="/some-article">
          <a>Card title</a>
        </Link>
      </h2>
      <p>Lorem ipsum, dolor sit amet, consectetur adipiscing elit. [...]</p>
    </BlockLink>
  )
}

More advanced example

const Cards = ({ cards }) => {
  return (
    <ul>
      {cards.map((card) => {
        return (
          <BlockLink key={card.id} tag="li" className="card">
            <h2>
              <Link href={card.href}>
                <a>{card.title}</a>
              </Link>
            </h2>
            <p>{card.text}</p>
          </BlockLink>
        );
      })}
    </ul>
  );
};

Note: The block will navigate to the href of the first descendant <a href="..."> element. Although the BlockLink component tries not to interfere with other clickable elements, the best UX is achieved if it contains one link only.

Props

prop default value description
tag 'div' The HTML element used to wrap the block.
style {cursor:'pointer'} Inline CSS to apply to the wrapper. Not recommended for elaborate styling, but useful to override the default.
children Everything inside <BlockLink>...</BlockLink> will become part of the clickable block. See props.children.
... All other props will be passed to the wrapper element.

License

MIT © marcvangend