ARIA Descriptions in React 19 with ShadCN

Accessibility is a core part of building modern web apps, and in React 19 — especially when using ShadCN UI components — proper use of ARIA labels is essential.

Why ARIA Labels Matter

ARIA (Accessible Rich Internet Applications) attributes help screen readers and assistive technologies interpret user interface components. In many cases, components in ShadCN will throw warnings if required ARIA details are not provided.

ShadCN Error

@radix-ui_react-dial….js?v=53928bc3:1188 Warning: Missing `Description` or `aria-describedby={undefined}` for {DialogContent}.
(anonymous) @ @radix-ui_react-dial….js?v=53928bc3:1188
react-stack-bottom-frame @ react-dom_client.js?v=53928bc3:16242
runWithFiberInDEV @ react-dom_client.js?v=53928bc3:726
commitHookEffectListMount

Setting ARIA Attributes

There are multiple ways to set ARIA attributes in ShadCN:

1. Using Standard HTML

Why Prefer Semantic HTML?

Semantic HTML elements like <button>, <a>, <nav>, <form>, <alert>, <h1>, etc, are already understood by screen readers and browsers. They come with built-in keyboard interactions and accessibility behaviors.

For example:

Use semantic HTML:

<button>Submit</button>

Manually specify some text

Most components allow passing standard ARIA attributes directly as props:

If the text is already displayed on the screen elsewhere within another element. Then, provide the data by referencing the element by document id. The referenced elements text content can then be used for the aria description. Using elements like <div> may work but the user may struggle to invoke focus on. Unlike <button elements, div elements do not have out-of-the-box accessibility features by default. Users of a screen reader may be unable to navigate to the element, and when moving will skip over it and its aria description. Instead, jumping ahead to a element that captures the movement (like a <input type=.

<div aria-labelledby="some-element-id"></div>

While similar to a <div, an <article or <main would be better, but don’t support any label features, unlike an <input or <a. Articles do offer other semantic accessibility features to user agents.

Instead favor a component that uses a <button or native element under-the-hood.

<Button aria-label="Submit form">Submit</Button>

This is the simplest and most common approach.

2. Wrapping with Standard Elements

If the component does not support direct ARIA props or you want more control:

<div role="button" aria-label="Open menu">
  <MenuIcon />
</div>

3. Using the ShadCN elements

When using components like the dialog component, the aria description is taken from the text content of the DialogDescription component.

Using he natural text contents

<>
  <Dialog>
    <DialogTrigger>Open</DialogTrigger>
    <DialogContent>
      <DialogHeader>
        <DialogTitle>Are you absolutely sure?</DialogTitle>
        <DialogDescription>
          This action cannot be undone. This will permanently delete your account
          and remove your data from our servers.
        </DialogDescription>
      </DialogHeader>
    </DialogContent>
  </Dialog>
</>

Using manual label – with the DialogDescription component removed, what description will be used? There is none provided by default, to prevent any warning and provide the information, you must specify it. While also overriding the aria description reference property on the component. By passing an undefined value to the aria-describedby property it will prevent causing the default <Dialog ShadCN component from showing an error.

return <>
  <Dialog>
    <DialogTrigger>Open</DialogTrigger>
    <DialogContent aria-describedby={void 0} aria-label={`Some label here`}>
      <DialogHeader>
        <DialogTitle>Are you absolutely sure?</DialogTitle>
      </DialogHeader>
    </DialogContent>
  </Dialog>
</>

Common Pitfalls

  • Missing aria-label or aria-labelledby: Interactive components like buttons and icons often require descriptive ARIA attributes. Omitting them can lead to accessibility issues and warnings.
  • Unclear roles: Applying ARIA attributes without defining a proper role (like button, dialog, or navigation) can cause screen readers to misinterpret the element.
  • Redundant or conflicting labels: Make sure ARIA labels do not contradict visible text or other accessibility tags.
  • Overuse of ARIA: Prefer semantic HTML elements whenever possible before reaching for ARIA.