Skip to content

Repository files navigation

A11yServerErrorBridge

Accessible server-error normalization, field mapping, rendering, focus recovery, localization, and optional integration with existing form plugins. Application code owns fetch() and passes error payloads to the bridge.

Installation

The package is not currently published. After publication, install it with one package manager:

npm install a11y-server-error-bridge
pnpm add a11y-server-error-bridge
yarn add a11y-server-error-bridge

For local development, run npm install and npm run build:dist before opening an example.

Basic usage

Start with native, labelled form controls. The bridge enhances the form; it does not replace its semantic structure.

<form id="account-form">
  <label for="email">Email address</label>
  <input id="email" name="email" type="email">
  <button type="submit">Save account</button>
</form>
import { createServerErrorBridge } from 'a11y-server-error-bridge';
import 'a11y-server-error-bridge/styles.css';

const form = document.querySelector<HTMLFormElement>('#account-form');
if (!form) throw new Error('Account form not found');

const bridge = createServerErrorBridge(form);
bridge.applyErrors({ fields: { email: 'Already used' }, form: ['Please review the form'] });

Supports fields envelopes, flat field objects, arrays of { field, message }, malformed fallback, and the optional adapters/problem-details subpath. Server messages are rendered with textContent, not HTML. Unknown fields default to promotion into form errors; choose retain or ignore with unknownFieldStrategy.

Public API

The main entry exports A11yServerErrorBridge, createServerErrorBridge, initServerErrorBridges, DEFAULT_OPTIONS, SELECTORS, CLASSES, ATTRIBUTES, EVENTS, and the public TypeScript contracts.

Important options:

Option Default Purpose
focusOnApply "auto" Focus an addon summary, the form-error region, or the first resolved control.
unknownFieldStrategy "form" Promote, retain, or ignore errors without an eligible control.
messageMode "first" Render the first field message or all field messages.
clearOnInput / clearOnChange true Clear the bridge-owned error for an edited control.
clearFormErrorsOnEdit false Also remove current form-level output when a resolved field is edited.
useAriaErrorMessage true Add aria-errormessage alongside aria-describedby.
fieldAliases {} Map backend keys to a control key, element, or resolver.
addons [] Install opt-in integration contracts.

Instances expose applyErrors(), normalizeErrors(), clearField(), clearErrors(), focusOnError(), locale and adapter registration methods, state getters, and idempotent destroy().

Structured package metadata is available without initializing the plugin:

import { docs } from 'a11y-server-error-bridge/docs';

Accessibility decisions

The bridge preserves existing aria-describedby, aria-invalid, and aria-errormessage values, then restores them on field clear, full clear, and destroy. Generated error IDs are private and unique to each bridge instance. Supplied [data-a11y-server-error-for] containers keep their author-provided IDs and content; the bridge adds and removes only its own message output.

clearField(field) accepts either the backend field key, the resolved control name or ID, or the resolved control element. Aliases do not require a second cleanup call: editing or clearing the mapped control removes its visible error, invalid state, and bridge-owned ARIA references together.

const bridge = createServerErrorBridge(form, {
  fieldAliases: { email_address: 'email' },
});

bridge.applyErrors({ fields: { email_address: 'Already used' } });
bridge.clearField('email');

The bridge supports focus recovery and avoids duplicate live regions by default. Final applications still require testing with their actual markup, backend responses, keyboard flows, browsers, translations, and screen readers.

See TESTING.md for the automated coverage matrix, supported browser assumptions, WCAG mapping, manual screen-reader checks, and known limitations.

These error identification and reference guarantees support WCAG 2.2 criteria 1.3.1 (Info and Relationships), 3.3.1 (Error Identification), and 4.1.2 (Name, Role, Value). They do not by themselves establish conformance for the surrounding application.

Keyboard and focus

The bridge adds no custom keyboard commands. Native buttons and controls retain their normal Tab, Shift+Tab, Enter, and Space behavior. Focus moves only when applyErrors() or focusOnError() requests recovery. Smooth recovery scrolling is reduced to auto when prefers-reduced-motion: reduce is active.

Lifecycle events

Events bubble from the form, are non-cancelable, and use the a11y-server-error-bridge: prefix.

Event key Trigger and important detail
init Synchronous bridge initialization completed.
beforeApply An application cycle started; the existing bridge state is cleared next.
beforeNormalize / normalize Normalization started/completed; completion includes field and form counts.
fieldResolved / fieldUnresolved A backend key was matched or could not be matched.
integrationConflict More than one addon claimed the same field-errors or form-errors rendering surface.
focus Focus recovery succeeded and reports addon, form-error, or first-invalid.
apply Rendering and focus recovery completed.
fieldClear / clear One field or the current bridge-owned state was cleared.
localeChange Current errors were rerendered with another locale.
error Normalization or addon installation/application/reveal failed safely.
destroy Cleanup completed. Repeated destroy() calls are no-ops.

Calling applyErrors() emits beforeApply, then clear, normalization and field-resolution events, optional conflict/focus events, and finally apply.

Optional addons

Concrete addons are available only from explicit subpaths:

  • a11y-server-error-bridge/addons/form-validator
  • a11y-server-error-bridge/addons/error-summary
  • a11y-server-error-bridge/addons/async-button
  • a11y-server-error-bridge/addons/conditional-fields

The root entry does not import optional peers. Supplying an existing peer instance gives deterministic synchronous behavior and leaves ownership with the application. createIfMissing uses an asynchronous dynamic import; an immediate first applyErrors() may therefore use the core fallback before the peer is ready. Addon installation rejections are reported through EVENTS.error.

When one field is cleared, the form-validator and error-summary addons resynchronize their remaining field errors instead of clearing or retaining stale external output.

Styling

Import a11y-server-error-bridge/styles.css. Public custom properties include:

  • --a11y-server-error-bridge-error-color
  • --a11y-server-error-bridge-border-color
  • --a11y-server-error-bridge-background
  • --a11y-server-error-bridge-gap
  • --a11y-server-error-bridge-focus-outline

The package also exposes component classes through CLASSES. Variables beginning with --_ are private implementation details.

Privacy and security boundary

The package performs no network requests, analytics, storage, URL synchronization, clipboard access, or form-value persistence. It keeps normalized messages in memory for the instance lifetime and renders server strings with textContent. Applications remain responsible for deciding what payload data they pass to the bridge and what they log, transmit, or retain.

Examples

The examples use built local files and simulated payloads. The package is not currently published to npm.

Limitations

  • The bridge does not submit forms, own requests, translate application messages, or define the application’s live-region policy.
  • The default renderer does not cross shadow-root boundaries or manage application portals.
  • Optional peer creation paths require those peer packages and application-level integration testing.
  • Automated DOM and Chrome checks do not establish screen-reader or cross-browser conformance.

About

Accessible server-error normalization, field mapping, rendering, focus recovery, localization, and optional integration with existing form plugins. Application code owns `fetch()` and passes error payloads to the bridge.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages