Skip to content

Fix "has an image with no non-empty alt text" (DS-A01)

Every image needs real alt text, including decorative ones. Where to put it for markdown, img and Frame.

reed check or reed build fails with one of two messages, depending on how the image was written:

txt
✗ [DS-A01] content file "guides/setup.mdx" has an image with no non-empty "alt" text
✗ [DS-A01] content file "guides/setup.mdx" has an <img> with no non-empty "alt" text
check failed.

The first is a markdown image, ![](...). The second is an <img> element — on its own, inside a Frame, or inside a {...} expression. The message names the file but not the line, so a page with several images needs a search.

DS-A01 is an accessibility error, not a warning. An image without alt text is announced by a screen reader as an unlabeled graphic, or by its file name, and the reader learns nothing.

The check fails an image when its alt text is missing, empty or whitespace-only. All of these fail:

mdx
![](./images/dashboard.png)
![ ](./images/dashboard.png)
<img src="./images/dashboard.png" />
<img src="./images/dashboard.png" alt="" />

Two of those surprise people:

  • alt="" fails. In plain HTML an empty alt marks an image as decorative. Reed has no decorative-image exemption and no flag to add one.
  • Images inside components are checked too. The walk covers the whole page, so an image inside a Frame, Card, Tab or Accordion is held to the same rule.

For a markdown image, the alt text goes between the square brackets:

mdx
![Dashboard listing three active projects and two pending invitations](./images/dashboard.png)

For an <img>, it is the alt attribute. A raw <img> only works with an absolute https:// URL; a page-relative src is not resolved (see Images not showing):

mdx
<img src="https://cdn.example.com/dashboard.png" alt="Dashboard listing three active projects and two pending invitations" />

Say what the image shows and why it is there, in a sentence or less. Skip “Image of” — the screen reader already announces an image. “Screenshot” passes the check and tells a listener nothing, so it is not a fix.

For an image in your content directory, put the markdown image directly inside the Frame and write the alt text in the brackets as usual. It no longer needs a <div> around it:

mdx
<Frame caption="The dashboard after your first deploy">
![Dashboard listing three active projects](./images/dashboard.png)
</Frame>

For an image at an absolute URL, an <img> with alt is the element child:

mdx
<Frame caption="The dashboard after your first deploy">
<img src="https://cdn.example.com/dashboard.png" alt="Dashboard listing three active projects" />
</Frame>

An empty Frame, or one whose only child is a paragraph mixing the image with other text, fails a different check:

txt
✗ [DS-S02] content file "guides/setup.mdx"'s "Frame" has 0 element child(ren); minimum required is 1

The caption does not replace alt. A caption is visible text for everyone; alt text stands in for the image itself. Write both.

There is no exemption, so write a short factual description instead of an empty one:

mdx
![Reed logo](./images/reed-mark.svg)
<img src="https://cdn.example.com/divider.svg" alt="Decorative divider" />

Then ask whether the image needs to be on the page at all. A purely decorative image in documentation is usually better removed.

The message has no line number. Search the file for images with nothing between the brackets and for <img> tags, then read each alt:

sh
grep -nE '!\[ *\]\(|<img' content/guides/setup.mdx
sh
reed check 2>&1 | grep -c 'DS-A01'

Expect 0, and a final check passed. Then read your alt text back without looking at the images. If a sentence would not tell you what the picture shows, rewrite it — the check proves alt text exists, not that it is useful.