Skip to content
Case Studies

Building a customer portal around accessibility

  • Next.js
  • TypeScript
  • Accessibility
  • Tailwind CSS
  • React Testing Library
Design and implementation
WCAG 2.1
design approach
Mobile-first
co-led frontend from scratch
Greenfield

Make the requirement explicit

I joined in March 2023 and co-led the frontend of a new customer portal. We were starting from scratch. There was no existing interface to retrofit, and the people using it would be filing disability claims.

Understanding that audience led me to raise accessibility with the team. I wrote a specification and brought the priorities into the discussion. We agreed to include them in the frontend work.

WCAG 2.1 was the current version then. I used it while writing the specification and building the interface. It gave me a reference for decisions that would otherwise be easy to leave implicit. Keyboard behavior belongs in the discussion about a component’s API. The way a screen reader encounters the content belongs in the discussion about its structure.

We also worked mobile-first. At that size, the space a control needs and the amount of scrolling become hard to ignore. Tap targets and the clarity of controls were part of the layout decisions early.

Start with the element

I started with semantic HTML. A native button already has a role and keyboard behavior. A clickable div needs that behavior added and maintained. The two can look identical. Choosing the element decides how much of the interaction we have to build ourselves.

I carried that approach into React Testing Library by querying components through their accessible roles. The query becomes part of the check: the component has to expose the role the test expects before the interaction can run.

For example, getByRole('button') will find a native button. It won’t find a div that only has a click handler. That’s a small example of what the testing approach checks, not code taken from the portal. A change can preserve the appearance of a control while losing the semantics that the query depends on.

Use the interface

I also used the interface with a keyboard. Component tests follow the interactions written into them. Using the interface myself let me check behavior outside those paths.

Finding a control by its role doesn’t tell you where keyboard focus goes after the control changes the page. That needs its own check. The illustration below models the distinction: its simulated structural checks pass while the keyboard path fails to reach the next step. Switch the focus behavior and try the same sequence again.

or drive it yourself
Conceptual keyboard-focus example. Try the controls to compare unmanaged and managed focus. This is not a recording of the portal or a defect found in it.

Following through

The accessibility specification became part of the frontend work with the team’s agreement. My responsibility continued through implementation and personal testing, alongside the broader frontend work I co-led. I also encouraged QA to include keyboard-based test cases.

I haven’t confirmed how widely those QA cases were adopted, and I didn’t document a full conformance review before release. This account covers WCAG-guided implementation and my own checks. It doesn’t establish verified WCAG conformance.

Writing the requirement down was the beginning. Someone still had to make the component decisions and use what we’d built. I took responsibility for that follow-through. That’s the part of this work I want to carry into another product.