0tokens

Apply for AI Grants India

Financial support for innovators building the future of AI in India.

Apply now

Chat · how to build accessible react apps

How to Build Accessible React Apps in 2026

  1. aigi

    React makes it easy to compose rich interfaces, but component reuse alone does not make an application accessible. Accessibility must be designed into the UI primitives, routing, state changes, forms, and testing workflow from the start. This guide explains how to build accessible React apps that are usable with keyboards, screen readers, magnification, voice control, touch devices, and other assistive technologies.

    For Indian teams building products for multilingual and mobile-first audiences, accessibility also improves general usability: clear labels help users with low literacy, predictable focus helps small-screen users, and resilient forms reduce failure on slower networks or older devices. Treat accessibility as a product requirement, not a final audit.

    Start with semantic HTML

    The strongest accessibility implementation usually starts with the browser’s native behaviour. Use the element that already expresses the interaction you need:

    • Use <button> for actions and <a href> for navigation.
    • Use <nav>, <main>, <header>, <footer>, and <aside> to expose page landmarks.
    • Use headings in a logical hierarchy. A page normally has one primary <h1>, followed by headings that reflect content structure.
    • Use <form>, <label>, <fieldset>, and <legend> for grouped inputs.
    • Use lists for lists, tables for tabular data, and <dialog> carefully for modal workflows.

    Avoid building buttons from <div> elements. A native button provides keyboard activation, focus behaviour, and semantics without extra code. If a custom component must be interactive, its keyboard behaviour, focus styling, accessible name, and state must all be implemented explicitly.

    In React, JSX maps closely to HTML, but attribute names differ: use className, htmlFor, and camel-cased event handlers. Give every meaningful image useful alt text; mark decorative images with alt="". Do not put important information only in background images or placeholder text.

    Design accessible component APIs

    Accessibility becomes easier when shared components make the correct behaviour the default. Build primitives such as Button, TextField, Select, Dialog, Tabs, and Tooltip with clear contracts.

    A reusable field component should generate or accept a stable id, connect its <label> with htmlFor, and associate help and error text through aria-describedby. It should expose required and invalid states without relying on colour alone. A button component should support visible focus, disabled state, loading state, and an accessible name when it contains only an icon.

    Prefer native controls over custom ARIA widgets. ARIA can describe a custom control, but it does not automatically provide keyboard interaction or focus management. Follow the WAI-ARIA Authoring Practices when implementing complex patterns such as comboboxes, menus, grids, or tabs.

    This discipline matters especially in products with AI-driven interfaces. If your application includes conversational or voice features, study the interaction and fallback considerations in how to build a voice agent and ensure that every voice-only action has an equivalent visible and keyboard-operable path.

    Use ARIA carefully

    The first rule of ARIA is simple: do not add ARIA when native HTML already provides the correct semantics. Incorrect roles or states can make an interface less usable for screen-reader users than plain HTML.

    Common, appropriate uses include:

    • aria-label or aria-labelledby for controls whose visible text is absent or insufficient.
    • aria-describedby to connect controls with instructions or validation messages.
    • aria-expanded and aria-controls for disclosure buttons.
    • aria-current="page" for the active navigation link.
    • aria-live="polite" for non-urgent status updates, such as a successful save.
    • aria-invalid="true" when a field fails validation.

    Do not use aria-hidden="true" on a focusable element or on content that a keyboard user still needs. Keep live regions stable in the DOM and update their text, rather than repeatedly mounting and unmounting them. Test announcements with the screen readers your users actually rely on.

    Make single-page navigation understandable

    Client-side routing changes content without a traditional page load, so users may not know that navigation occurred. After a route change, update the document title and announce or move focus to the new page heading. Do not move focus on every minor state update; focus should follow a meaningful context change.

    A practical route-change pattern is:

    1. Render the new page and its primary heading.
    2. Set document.title to describe the destination.
    3. Move focus to a non-interactive heading or page container with tabIndex={-1}.
    4. Ensure the skip link remains available at the top of the page.

    For modals, place focus on the dialog or its first meaningful control, keep focus inside while open, close on Escape when appropriate, and return focus to the trigger. Use an established dialog primitive rather than improvising a focus trap. Never hide the underlying page from assistive technology unless the modal truly blocks interaction with it.

    Build forms that help users recover

    Accessible forms explain what is required before submission and identify errors in context. Every field should have a persistent label; placeholder text is not a substitute because it disappears during entry and often has weak contrast.

    Useful form practices include:

    • Give errors specific, actionable messages such as “Enter a 10-digit mobile number.”
    • Place the error near the relevant field and connect it with aria-describedby.
    • Preserve entered values after validation fails.
    • Identify invalid fields programmatically with aria-invalid.
    • Provide a summary for long forms and link each summary item to its field.
    • Use suitable autocomplete values and input types.
    • Avoid aggressive validation that interrupts typing or announces every keystroke.

    For Indian users, test mobile-number, address, language, and identity-related fields with realistic data. Do not assume that a single rigid format works across states, scripts, or input methods. When an AI feature extracts intent or entities from short user messages, expose the extracted result and offer an editable confirmation path; guidance on intent extraction in short text is relevant to this kind of interface.

    Support visual, keyboard, and touch access

    Use colour contrast that meets WCAG 2.2 AA targets: generally 4.5:1 for normal text and 3:1 for large text. Do not communicate success, danger, or selection through colour alone. Pair colour with text, icons, patterns, or state labels.

    Keep a clearly visible :focus-visible indicator with sufficient contrast. Never remove the browser outline without providing a stronger replacement. Check hover, focus, active, disabled, error, and visited states. Ensure touch targets have adequate size and spacing, and that interactions do not depend on hover alone.

    Respect user preferences where possible:

    • Honour prefers-reduced-motion for transitions and animated loading states.
    • Support zoom and reflow without hiding content or forcing horizontal scrolling.
    • Keep text readable when users increase browser font size.
    • Provide captions or transcripts for audio and video.
    • Offer language choices and ensure translated strings do not break labels or controls.

    These practices are useful for any India-focused product serving varied devices and connectivity conditions, including the broader accessibility concerns that arise when building AI apps for the next billion users in India.

    Test accessibility continuously

    Automated tools catch only a portion of accessibility defects, but they should run on every pull request. Use eslint-plugin-jsx-a11y during development, axe-core or jest-axe for component and integration tests, and Lighthouse or axe DevTools for browser checks. Test rendered states, not just the default story: open dialogs, invalid forms, loading states, empty results, and error boundaries.

    Manual testing remains essential:

    • Navigate the complete product with Tab, Shift+Tab, Enter, Space, and arrow keys where relevant.
    • Test at 200% zoom and with reflow on a narrow viewport.
    • Check focus order and whether focus is ever lost or trapped unexpectedly.
    • Test with at least one screen reader, such as NVDA on Windows or VoiceOver on macOS and iOS.
    • Turn off CSS or inspect the page with a browser’s accessibility tree when debugging structure.
    • Include people with disabilities in usability research and acceptance testing.

    Write accessibility acceptance criteria alongside feature requirements. A component is not finished if it works only with a mouse, has no usable error state, or fails when content is translated or enlarged. For teams building more complex AI systems, the same principle applies to agent interfaces and orchestration; accessibility should be part of the product contract described in building distributed systems with AI agents, not an isolated frontend ticket.

    A practical definition of done

    Before releasing a React feature, confirm that:

    • Every interactive element has a clear accessible name and native or correctly implemented semantics.
    • The entire flow works from the keyboard.
    • Focus is visible, logical, and managed after navigation, dialogs, and dynamic updates.
    • Forms expose labels, instructions, errors, and required states.
    • Contrast, zoom, reflow, motion, captions, and colour-independent cues have been checked.
    • Automated checks run in CI and manual testing covers important user journeys.
    • Real users, including disabled users where possible, have influenced the design.

    Accessible React development is not a separate version of frontend engineering. It is disciplined component design, careful state management, and testing against how people actually use software. Build those practices into your codebase from the first component, and accessibility will scale with the product rather than becoming an expensive retrofit.

    Last updated 23 September 2026

AIGI may be inaccurate. Replies seeded from the guide above.