Building Warmth Care: A Case Study in NDIS Website Accessibility

We built the website for Warmth Care Support Services, a registered NDIS provider based in Winter Valley, Victoria. This case study is a full technical breakdown of that build: the architecture, the accessibility engineering, the security decisions, and the trade-offs we made along the way. It is written for two audiences at once. If you are an SMB owner evaluating a web agency, the sections on outcomes and what to ask a prospective developer will matter most to you. If you are the technical or IT admin at an NDIS provider or similar organisation, the architecture and accessibility sections go deep enough to actually be useful.
A website for an NDIS provider carries a different kind of pressure than a normal small business site. The people visiting it are more likely than average to be using a screen reader, navigating by keyboard only, or relying on assistive technology to get through a form. If the underlying code is not genuinely accessible, the site fails the exact audience it exists to serve, no matter how good it looks.
TL;DR
We built the website for Warmth Care, a registered NDIS provider in Victoria, on Next.js and Sanity CMS. Beyond the build itself, we focused on real accessibility engineering rather than a bolt-on widget: full keyboard navigation, native skip-to-section links, CMS-managed alt text on every image, and a targeted colour contrast fix. The result is a 100/100 Lighthouse Accessibility and Best Practices score, full passes on every WCAG A and AA criterion checked by an automated conformance tool, and a manual review by an accessibility-experienced UI/UX designer. When reaching WCAG AAA would have meant overriding Warmth Care's brand colours, we held the line at AA and let the client make that call themselves. The build also has real security depth (CSP, bot protection, rate limiting) for a form that often handles a family's first contact with the service.
The Brief: What an NDIS Provider Website Actually Needs to Do
An NDIS provider website needs to explain the organisation's services clearly, give families and participants a low-friction way to make contact, and hold up to genuine accessibility scrutiny, since a meaningful share of its visitors rely on assistive technology.
The National Disability Insurance Scheme (NDIS) is the Australian Government's scheme for funding support and services for eligible people with disability. Registered NDIS providers, like Warmth Care, deliver those supports directly to participants and their families, across areas such as personal care, community participation, daily living assistance, and more. For many families, a provider's website is the first point of contact, which sets a clear bar: the site needs to represent the organisation's services accurately, make it straightforward to get in touch, and actually work for an audience where assistive technology use is common.
Beyond content, the brief had three hard technical requirements: a contact experience robust enough to handle sensitive first-contact enquiries, a content system the Warmth Care team could run themselves without a developer on call, and an accessibility standard that could survive scrutiny from an audience with every reason to check.
Architecture Overview: Why Next.js and Sanity
The site is built on Next.js using the App Router, paired with Sanity as a headless CMS, connected through incremental static regeneration rather than full server-side rendering or a static build.
We chose a headless CMS over a traditional platform like WordPress for a specific reason: content structure needed to be enforced, not just typed into a rich text box. Sanity lets us define a strict schema for services, news posts, team members and site settings, so an editor cannot accidentally break a page layout by pasting in unstructured content. The trade-off is a steeper setup cost against a faster editing experience once it is running.
Incremental static regeneration (ISR) sits at the centre of the architecture. Rather than rendering every page fresh on each request, or rebuilding the entire site every time a piece of content changes, pages are cached and automatically revalidated on a timer, roughly every 60 seconds. In practice, that means a service description edited in Sanity appears live on the public site within about a minute, with none of the delay of a full redeploy and none of the server load of rendering everything on every visit.
Sanity Studio, the actual content editing interface, is embedded directly inside the same codebase at a dedicated admin route rather than run as a separate application. That keeps content management and the public site in lockstep as one deployable unit, which matters for a small organisation without a dedicated DevOps function.
Layer | Technology | Why |
|---|---|---|
Framework | Next.js, App Router | Incremental static regeneration, strong SEO defaults, mature ecosystem |
Content | Sanity CMS, embedded Studio | Structured schema, GROQ query language, no separate admin deployment |
Forms | Server-side validation, Cloudflare Turnstile | Genuine bot protection without a CAPTCHA experience for real users |
Fonts | next/font (DM Sans, Libre Baskerville) | Self-hosted delivery, no third-party font request blocking render |
Hosting | Vercel | Native ISR support, edge network, simple deployment pipeline |
Content Model and Editorial Workflow
Warmth Care's team manages the entire site, including service descriptions, news posts, team profiles, image alt text and brand theme colours, through the Sanity Studio interface without touching code.
Every image field in the schema now carries a dedicated alt text field alongside it, so as content is added, alt text is written at the point of upload rather than patched in after the fact or left to a generic fallback. This matters more than it sounds. A CMS that makes alt text optional or buried tends to end up with alt text that never gets written. Making it a first-class field next to the image itself changes that default.
Brand theme colours are also CMS-managed. The design tokens (the actual hex values used across headings, body text, buttons and backgrounds) are stored in Sanity and mapped into CSS custom properties at render time, rather than hardcoded into a stylesheet. A colour adjustment is a content change made by Warmth Care's team, not a development ticket that has to go through us.
Accessibility Engineering: How We Got a Perfect Lighthouse Score
The build scores 100 on both Lighthouse Accessibility and Best Practices audits, passed every WCAG A and AA criterion checked by an automated conformance tool, and was manually reviewed by a UI/UX designer with dedicated accessibility experience, on top of semantic HTML structure, full keyboard navigation, section-level skip links, and CMS-managed alt text.
A perfect automated score is worth being precise about, so we ran more than one kind of check. Lighthouse audits what a browser can verify programmatically: heading order, contrast ratios, ARIA attributes, labelled form fields, and similar signals. To check against actual WCAG success criteria rather than Lighthouse's approximation of them, we also ran the site through an automated WCAG conformance tool, then had a UI/UX designer with dedicated accessibility experience manually review both the tool's results and the live site. The full breakdown, and an important caveat about what that tool actually measured, is below.
Here is what the score is actually built on:
Keyboard navigation. Core flows and interactive components, menus, service listings, form controls, the testimonial modal, can be operated without a mouse. Tab order follows a logical reading sequence, and controls respond to the key patterns a keyboard-only user expects (Enter and Space to activate, Escape to close overlays).
Section-level skip navigation. Pressing Tab on page load surfaces skip options that jump directly to specific sections of the page (main content, navigation, footer), rather than a single generic "skip to content" link. For a keyboard user working through a long service page, that is the difference between one tab press to reach what they want and dozens.
CMS-managed alt text. Every image field in the CMS now has a dedicated alt text field sitting alongside it, prompting for a specific description at the point content is added rather than relying on a filename or an empty fallback. Decorative elements (background shapes, purely visual dividers) are correctly marked to be ignored by screen readers, so assistive technology output stays focused on content that matters rather than being cluttered with noise.
Semantic landmark structure. Header, navigation, main and footer regions are marked up correctly, with a single clear heading hierarchy on every page and the root language attribute set for Australian English.
ARIA implementation on interactive components, including a fully accessible modal dialog for testimonials, with role="dialog", aria-modal, and keyboard support built directly into the component rather than added as an afterthought.
A targeted colour contrast pass. An early audit flagged that the brand's accent orange, used on white backgrounds in a couple of places, sat close to the WCAG 2.2 AA threshold for text readability. We corrected the affected token pairings rather than leaving contrast to be patched at runtime by an overlay tool.
An accessibility overlay widget also sits on the site, giving visitors optional extras like font resizing and a contrast toggle. We were deliberate about where that widget sits in the stack. Early in the build we trialled a different overlay vendor before switching to the current one, because the first option did not give us the toolbar behaviour we wanted. The widget is additive. The semantic markup, ARIA implementation, keyboard support and contrast fixes above are the actual foundation, and they would hold up with or without the widget running.
The AA Versus AAA Decision
Every WCAG A and AA criterion checked by an automated conformance tool came back passing, and the site came within one checked criterion of full AAA, but reaching AAA would have meant overriding the client's brand colours, so we held the line at AA rather than treat a score as more important than the client's actual identity.
Chasing the highest possible score is not automatically the right engineering decision. Full WCAG AAA conformance would have required changing specific brand colours that Warmth Care had already chosen as part of their identity. AAA is also a genuinely higher bar than most organisations, including large ones, ever attempt, since WCAG itself does not recommend AAA as a general requirement for entire sites. WCAG AA is the standard nearly every accessibility framework and legal guideline treats as the practical target.
We put that trade-off to Warmth Care directly rather than deciding it quietly on their behalf. They chose to keep their brand colours and remain at AA. We think that was the right call, and we would have supported either decision, because it is theirs to make.
Independent WCAG Conformance Results
In addition to the Lighthouse audit, we tested the live site against WCAG success criteria using an automated conformance checker from Friendlycaptcha, then had the results manually reviewed by a UI/UX designer with dedicated accessibility experience, since automated testing alone cannot confirm every criterion.
One clarification worth making plainly: the numbers below reflect the specific criteria that tool evaluated and categorised as testable for this page, not the complete WCAG success criteria set. The full WCAG 2.2 standard defines 55 combined Level A and AA success criteria, and 86 across all three levels including AAA. Automated tools can only reliably check a subset of these programmatically; a meaningful portion of WCAG, particularly around things like meaningful reading order, plain language, and context-dependent alternative text, requires human judgement rather than a script. That is exactly why the automated pass was followed by a manual review rather than treated as the final word.
Standard | Result (per Friendlycaptcha's automated check) |
|---|---|
WCAG A | 9 of 9 evaluated criteria passed |
WCAG AA | 14 of 14 evaluated criteria passed |
WCAG AAA | 15 of 16 evaluated criteria passed |
EN 301 549 | 13 of 13 evaluated criteria passed |
Lighthouse Accessibility | 100 |
Lighthouse Best Practices | 100 |
The single AAA gap is the brand colour trade-off described above. Two additional checks were flagged by the tool as requiring human confirmation rather than being auto-resolved, which is exactly what the manual accessibility review covered. We are presenting this as a strong pass on the criteria that can be automatically verified, backed by a manual review, not as a claim of full formal WCAG AA certification, which requires a comprehensive audit against the entire criteria set by a qualified assessor.
Security Architecture for a Sensitive Enquiry Form
The contact form is protected by a strict Content Security Policy, server-side bot detection through Cloudflare Turnstile, origin allowlisting, and request rate limiting, reflecting application hardening practices broadly consistent with the ACSC Essential Eight framework.
An enquiry submitted through an NDIS provider's website is often a family's first contact with a service, sometimes made in a stressful moment. We treated the security of that form with more depth than a typical small business brochure site tends to get.
Content Security Policy. Response headers explicitly allowlist only the third-party origins the site actually needs, the CMS image CDN, the accessibility widget script, Cloudflare Turnstile, and Google Maps for the contact page. Nothing else is permitted to execute, which closes off a wide category of script injection attacks by default rather than by exception.
Bot protection that verifies server-side. Cloudflare Turnstile runs on the form, but the verification happens on the server, not the client. A submission is not trusted because the browser says it passed a check, it is trusted because the server independently confirmed it with Cloudflare.
Origin checks and rate limiting. The API routes handling contact, careers and feedback submissions check the request origin against an allowlist and apply rate limiting, so the endpoints cannot be trivially scripted or hammered.
Server-side validation on top of client-side validation. Every submission is re-validated on the server (required fields, email format, allowed service selections, length limits) and HTML-escaped before being sent through, regardless of what the client-side form already checked. Client-side validation is a user experience feature. It is never treated as the actual security boundary.
Minimal data retention. The site does not store form submissions in a database. Enquiry data is transmitted directly to Warmth Care's own email inbox through Resend, the transactional email service handling delivery, and exists nowhere else in the site's infrastructure. There is no separate customer data store on our end to secure, back up, or eventually have to delete, which is a smaller attack surface than a typical brochure site with a CRM integration or a submissions table.
One deliberate architectural choice worth mentioning for a technical audience: the security headers are set through Next.js configuration rather than middleware, which keeps the CSP simpler and more predictable to reason about than handling it at the middleware layer. It is a small decision, but it reflects the kind of ongoing vigilance that infrastructure choices actually need, not just the ones that are visible on the page.
Performance and Caching Strategy
Content freshness is handled through timed incremental static regeneration rather than on-demand webhook revalidation, fonts are self-hosted through Next.js's font pipeline, and images are served through Sanity's CDN with explicit sizing parameters per use case.
The ISR revalidation window (roughly 60 seconds) was a deliberate trade-off. On-demand revalidation, where a webhook from Sanity triggers an instant update the moment content is published, is a more responsive pattern, and it is on our roadmap for this site. For a small organisation's content update cadence, a one-minute delay is not a meaningful cost, and the simpler timed approach means fewer moving parts to maintain.
Fonts (DM Sans and Libre Baskerville) are loaded through Next.js's built-in font optimisation, which self-hosts the font files and sets display: swap, so text renders immediately in a fallback font rather than staying invisible while a web font loads. Images are served through Sanity's image CDN with explicit width, height and fit parameters set per component, so a card thumbnail and a hero image each request an appropriately sized asset rather than the same oversized original.
SEO Technical Implementation
Every page pulls its own metadata, canonical URL and structured data directly from Sanity, with the sitemap and robots configuration generated dynamically from live content rather than maintained as static files.
Meta titles, meta descriptions and Open Graph tags are set per page through the CMS, with sensible fallbacks defined in code if a field is left empty. Structured data (JSON-LD) is in place for organisation and local business details sitewide, with article schema on news posts and breadcrumb schema where relevant. The sitemap is generated dynamically from the current set of published services and posts, so a new page gets indexed without anyone needing to remember to update a static sitemap file by hand.
The Results
Full passes on every WCAG A and AA criterion checked by an automated conformance tool, a 15-of-16 result on the AAA criteria checked (limited only by a deliberate brand colour decision), and a perfect Lighthouse Accessibility and Best Practices score, backed by manual review from an accessibility-experienced UI/UX designer.
The full breakdown is in the WCAG Conformance Results table above. The short version: nothing failed at the level that actually matters for a production site, the one AAA gap was a considered trade-off rather than an oversight, and the numbers were checked by a human, not just a tool.
Engineering Trade-offs and What's Next
No production build is finished, and being upfront about the current roadmap items, including moving to Next.js's image optimisation component and on-demand content revalidation, is part of how we approach every build.
Two items are actively on the roadmap for this site rather than already shipped. Images currently render through Sanity's CDN with manually specified sizing rather than through Next.js's native image component, which would add automatic responsive image generation on top of what is already there. Content revalidation is timed rather than webhook-triggered, which is a reasonable trade-off at Warmth Care's current publishing cadence but would become worth changing if that cadence increases.
Neither of these affects the accessibility scores or the security posture. We are including them because a technical case study that only lists what is finished is not actually useful to another IT admin reading it, and it is not an honest picture of how software gets built.
What This Means If You're Evaluating a Web Agency
A genuinely accessible website is the outcome of specific, checkable engineering decisions made throughout a build, not a widget installed after launch, and an agency confident in its work should be willing to show you exactly which decisions it made.
If accessibility genuinely matters to your organisation's users, and not just to a line on your marketing site, ask a prospective developer more specific questions than "is it accessible." Ask for the Lighthouse report. Ask which components have full keyboard support and which do not yet. Ask whether alt text is a required field in the CMS or an afterthought. An agency with a real, specific answer is a fundamentally different proposition to one that points at an overlay widget and calls it done.
If you are building or rebuilding a site where accessibility is a genuine requirement rather than a checkbox, Contact Us and we will talk through what that actually takes for your situation.
Frequently Asked Questions
What makes an NDIS provider website accessible, not just compliant-looking?
Genuine accessibility comes from the underlying code: semantic HTML, full keyboard support on core interactive flows, correct ARIA usage, section-level skip navigation, and colour contrast that actually meets WCAG 2.2 AA thresholds. An overlay widget can add convenience features on top, but it cannot fix inaccessible markup underneath it.
Does a 100 Lighthouse Accessibility score mean a website is fully WCAG compliant?
Not on its own. Lighthouse audits the accessibility signals a browser can check automatically, which is a strong and genuinely useful indicator, but formal WCAG or ADA compliance requires manual testing, including with real assistive technology, against the full standard.
Why does website security matter this much for an NDIS provider specifically?
An NDIS provider's contact form often handles first contact from families in vulnerable circumstances. Server-side validation, verified bot protection and rate limiting protect that data and keep the form reliable, in the same way any organisation handling sensitive enquiries should treat its intake channel.
What content management system does the site use, and can our own team manage it without a developer?
The site runs on Sanity, a headless CMS with a structured schema, embedded directly in the site so there is no separate admin platform to maintain. Warmth Care's team edits services, news, team profiles, image alt text and even brand colours themselves, without needing a developer for routine content changes.
How quickly do content changes go live after they're published in the CMS?
Most content changes appear on the live site within about 60 seconds, through timed incremental static regeneration. On-demand, instant revalidation through webhooks is a planned future improvement.
Is a perfect Lighthouse score enough to consider a website accessible?
It is a strong technical baseline, not a complete answer. We treat the automated score as one input alongside manual review of keyboard behaviour, screen reader output, and real content like alt text quality, since automated tools cannot fully evaluate how a page actually reads to someone using assistive technology.
Should a website always aim for WCAG AAA instead of AA?
Not necessarily. WCAG itself does not recommend AAA as a general requirement for entire sites, and reaching it can require trade-offs, such as overriding brand colours, that are not always worth making. WCAG AA is the level nearly every accessibility framework and legal guideline treats as the practical standard, and it is what we recommend for most organisations unless there is a specific reason to go further.
Ready to build something great?
We partner with ambitious businesses to create websites that convert. Let's talk about your project.


