Medusa is an open-source, Node.js and TypeScript headless commerce platform: it provides the admin, product and order data, and a commerce API, while the storefront is your own code, most often a Next.js application built from the Medusa starter. That architecture puts almost every accessibility decision in your hands, which is a strength and a trap. It is a strength because you are not fighting a rigid theme, so nothing stops you from shipping semantic, keyboard-friendly markup. It is a trap because the starter storefront is a starting point, not a certified accessible reference, and teams routinely style it, extend it, and ship it without ever testing the parts of a store that fail most often for disabled shoppers. Those parts are predictable. Product images pulled from Medusa carry no alt text unless you add and populate a metadata field, so galleries render with empty or filename alt attributes. Variant and option selectors, the swatches and dropdowns a shopper uses to pick a size or color, are frequently built as clickable divs with no radio semantics, no keyboard support, and no announcement of the selected value or of an out-of-stock combination. The cart drawer that slides in when someone adds an item often does not move focus, trap it while open, or restore it on close, so keyboard and screen reader users lose their place. Checkout, the most consequential flow in any store, is where missing labels, unannounced validation errors, and inaccessible payment widgets convert directly into abandoned orders. Because Medusa storefronts sell to EU customers, the European Accessibility Act applies, and an inaccessible checkout is both a compliance risk and lost revenue. This checklist walks the storefront the way a shopper using assistive technology does, from product page to confirmed order.

Common Accessibility Issues

critical

Product Images Rendered Without Alt Text

WCAG 1.1.1

Medusa product and variant images are stored as URLs with no alt text by default, and the starter storefront renders galleries and thumbnails with empty or filename-derived alt attributes. Screen reader users browsing a product hear nothing useful about how the item looks, which is exactly the information a product image exists to convey, and cannot tell the main image apart from the thumbnails.

How to fix:

Add an alt text field to product images through Medusa's product metadata or a custom field, and populate it with a description of what the image shows. Render that value on the image element in your storefront. For a gallery of the same product from different angles, give each image a distinct description such as 'Blue running shoe, side view' rather than repeating the product name, and treat purely decorative thumbnails consistently so they are not announced as unlabeled images.

critical

Variant and Option Selectors With No Keyboard or Radio Semantics

WCAG 4.1.2

Size and color pickers built from Medusa product options are commonly rendered as clickable divs or buttons with a visual selected state and no underlying semantics. Keyboard users cannot arrow between choices, screen reader users are not told these form a group or which option is selected, and an out-of-stock combination is often conveyed with color alone, so it is invisible to shoppers who cannot see the styling.

How to fix:

Build option selectors as a labeled radio group so the name, role, and current value are exposed and arrow keys move between choices. Give the group an accessible name like 'Choose a size'. Convey unavailable combinations with text or an explicit disabled state and an announcement, not color alone, and make sure the currently selected variant is announced when it changes so shoppers know which item they are about to add to the cart.

critical

Cart Drawer That Does Not Manage Focus

WCAG 2.4.3

The mini-cart or cart drawer that slides in when a shopper adds an item usually does not move focus into itself, does not trap focus while open, and does not return focus to the triggering control when closed. Keyboard users can tab into the page behind the drawer, and screen reader users may not even be told the drawer appeared, so the confirmation that an item was added is silently lost.

How to fix:

When the cart drawer opens, move focus to it and expose it as a dialog with an accessible name, trap focus within it while it is open, and allow the Escape key to close it. Announce that the item was added, for example through a status message, and restore focus to the add-to-cart button on close. Ensure the quantity steppers and remove buttons inside the drawer have real labels and are reachable and operable by keyboard.

critical

Checkout Form Fields Missing Labels and Error Announcements

WCAG 3.3.1

Checkout in a custom Medusa storefront frequently uses placeholder text instead of real labels, groups shipping and billing fields without programmatic association, and shows validation errors only as red borders or text that is never announced. Screen reader users cannot tell which field is which once a placeholder disappears, and cannot tell why a submission failed, which stalls the single most important flow in the store.

How to fix:

Give every checkout field a visible, persistent label programmatically associated with its input, and never rely on placeholder text as the only label. Group related fields, such as an address, so their purpose is clear. When validation fails, move focus to the first error or announce a summary, describe each error in text next to its field, and identify which field it belongs to, so a shopper using a screen reader can find and fix the problem without guessing.

serious

Price, Discount, and Stock Changes Announced by Color Only

WCAG 1.4.1

Storefronts show sale prices, applied discounts, and low-stock warnings using color and struck-through styling, and update the total in the cart without any announcement. A shopper who cannot perceive the color sees no discount, and a screen reader user who changes a quantity is not told the new total, so they cannot confirm what they are paying before checkout.

How to fix:

Convey sale pricing with text as well as styling, for example by marking the original price as struck through in an accessible way and stating the current price plainly. When the cart total or a line item updates in response to a quantity change or an applied code, announce the change through a polite status region so screen reader users hear the new value. Do not rely on color alone to signal low stock or a successful discount.

moderate

Storefront Shipped From the Starter Without an Accessibility Pass

WCAG 2.1.1

Teams clone the Medusa starter storefront, restyle it, add features, and ship without ever testing the result with a keyboard or screen reader. The starter is a functional reference, not a certified accessible baseline, so untested customizations introduce keyboard traps, unlabeled custom controls, and focus problems that no automated scan catches on its own.

How to fix:

Before launch, walk the whole purchase flow, product page to order confirmation, using only the keyboard, then again with a screen reader. Fix any control you cannot reach or operate, any focus that gets lost, and any state change that is not announced. Add this manual pass to your release checklist so each new feature is tested the same way, since automated tools catch missing labels and contrast but not broken keyboard flows.

Medusa-Specific Tips

  • Treat the Medusa starter storefront as a starting point, not a certified accessible baseline, and test the whole purchase flow before launch.
  • Add and populate an alt text field for product images through metadata, because Medusa stores image URLs with no text alternative by default.
  • Build variant and option selectors as labeled radio groups so keyboard users can arrow between choices and the selected value is announced.
  • Make the cart drawer a real dialog that moves, traps, and restores focus, and announces when an item is added.
  • Walk the full checkout with a keyboard and a screen reader, since checkout is where inaccessible forms turn directly into abandoned orders.

axe DevTools

A browser extension that audits your rendered storefront for missing alt text, unlabeled form fields, contrast failures, and missing roles on custom variant and cart controls.

Accessibility Insights for Web

A free Microsoft tool whose guided assessment and tab-order visualizer are well suited to checking the keyboard path through a product page, cart drawer, and checkout in a custom Medusa front end.

VoiceOver / NVDA

Screen readers for manually confirming that variant selection, cart updates, and checkout errors are announced correctly, which automated tools cannot verify on their own.

Frequently Asked Questions

Is the Medusa starter storefront accessible out of the box?

The starter is a functional, reasonably clean reference, but it is not a certified accessible baseline, and shipping it unchanged still leaves gaps. More importantly, almost no store ships it unchanged: teams restyle it, add variant pickers and promotions, and swap the payment step, and those customizations are where keyboard traps, unlabeled controls, and focus problems creep in. Because Medusa is headless, every one of those decisions is in your code, which means you own the accessibility of the result end to end. Treat the starter as a head start, then test the full purchase flow with a keyboard and a screen reader before launch rather than assuming the baseline covers you.

How do I make Medusa product images accessible when they have no alt text?

Medusa stores product and variant images as URLs with no alt text, so you have to supply it. Add an alt text field to your image data, either through product metadata or a custom field on the model, and populate it with a real description of what each image shows. Then render that value on the image element in your storefront rather than falling back to the filename or the product name. For a gallery, describe each angle distinctly, and for genuinely decorative thumbnails, handle them consistently so they are not announced as unlabeled images. The key point is that no front-end code can invent a description the data does not contain, so the fix starts in your content, not your components.

Further Reading

Other CMS Checklists