npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

a11y-server-error-bridge

v1.0.0

Published

Accessible server-error normalization, field mapping, rendering, focus recovery, localization, and optional integration with existing form plugins.

Readme

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.