Custom checks

You can extend Sa11y beyond checking for accessibility issues. For example, create checks that promote better usability, or encourage proper use of components and web style guidelines. All custom checks should be created within /src/sa11y-custom-checks.js.

How to create a custom check

You can create custom checks with just a few lines of JavaScript. There are two types of annotations you create: Button annotations appended at the source of the issue, and full page issues that are displayed within Sa11y's panel. There are several utilities functions and elements you can use.

Simply populate the results object to flag an issue.


  • element - Issue element (Element)
  • type - Type of issue: Error, Warning, or Pass. (String)
  • content - Tooltip message. (String)
  • inline - Display annotation inline with text. (Boolean)
  • position - Where to insert annotation. View insertAdjacentHTML() parameters. (String)
  • dismiss - A string that uniquely identifies the found issue used for all warnings.
    • All warnings must have have a dismiss key. Errors cannot be dismissed.
    • It's very important that the key is unique. It's recommended to pass the element's inner text for example. Use the Utils.prepareDismissal utility function to generate a key.

Page Issue

Simply pass a type and content to create a Page Issue that's displayed in the main panel.

  • type - Type of issue: Error, Warning, or Pass. (String)
  • content - Issue message. (String)


Both recipes below are included in sa11y-custom-checks.js for reference.

Overusing a component on a page

The example detects if more than one announcement is detected on a page, although it could be easily extended to anything. Too many slideshows? Too many accordions? You name it.

const $checkAnnouncement = find('.sa11y-announcement-component', 'root');
  if ($checkAnnouncement.length > 1) {
    for (let i = 1; i < $checkAnnouncement.length; i++) {
      const key = Utils.prepareDismissal($checkAnnouncement[i].textContent);
        element: $checkAnnouncement[i],
        type: Constants.Global.WARNING,
        content: C.ANNOUNCEMENT_MESSAGE,
        inline: false,
        position: 'beforebegin',
        dismiss: key,


This is an announcement component!
This is another announcement component!

Accordion component contains a form

Forms nested within accordion components can be problematic if it uses server-sided validation. The page will reload, and the accordion usually returns back to its closed state. This is problematic for everyone.

const $checkAccordions = find('.sa11y-accordion-example', 'root');
$checkAccordions.forEach(($el) => {
  const checkForm = $el.querySelector('form');
  if (!!checkForm && checkForm.length) {
      element: $el,
      type: Constants.Global.ERROR,
      inline: false,
      position: 'beforebegin',


Add or suggest a recipe

Share your recipe on GitHub.