Aria-live in JavaScript Frameworks
Tags: a11y, angular, vue, react
Published: 2021-05-01 03:40:28

The aria-live attribute makes it possible for assistive technology users (screen readers in particular) to be notified when status messages, errors, or page updates have happened. Examples would be a "you are logged in!" toast message or a global error message stating "There are multiple issues with the form, please correct".

The content within an aria-live region is automatically read by assistive technology when new content appears in that region. This allows for dynamic announcements or state changes on the site to be read to assistive technology users which makes the experience in your application easier to use. 

# The Problem in JavaScript Frameworks

Aria-live regions in general have struggled to announce properly in JavaScript frameworks due to the dynamic nature of them. Asynchronously adding content into the DOM makes it hard for assistive technologies to pick up the region and announce it. 

Initially developers would create live regions that were reusable components (see example below), which would include the aria-live attribute. The component would then dynamically be added into the DOM, and render the message. 

The result, assistive technology greatly struggled to read aria-live when it is not in the DOM on load of the page. The announcement was very inconsistent, and more often than not would not even be read. 


>Angular reusable component
``` ts
     @Component({
        selector: 'toast-message-component',
        template: `<div aria-live="assertive">
                   <span className="alertText">
                   {this.props.liveText}
                   </span>
                   </div>`
      })
     
```


# The Solutions

Luckily, over the past few years a few different types of solutions that are proven to work effectively have come to light that have greatly improved the use of aria-live in JavaScript frameworks.

## Live Regions on Load

One sure fire way to ensure live region properly announces is to always include it in your application. 

By simply including a live region container across your entire application or having the component render the live region on load, and then dynamically adding the message or content you wish too have announced then it will properly announce every single time!

>React on load aria-live component 
``` jsx
function LiveAnnouncer({ liveText }) {
  const setText = (text) => {
    if (liveRef.current) {
      const newText = document.createElement("span");
      newText.innerHTML = text;
      liveRef.current.appendChild(newText);
    }
  };
  const clearText = () => {
    if (liveRef.current) {
      liveRef.current.innerHTML = "";
    }
  };
  useEffect(() => {
    clearText();
    setTimeout(() => {
      setText(liveText);
    }, 50);
  }, [liveText]);
  return (
    <div aria-live="assertive" />
  );
}
```

## Lazy Load Components

Lazy loading a component allows the JavaScript payload of a component or a page to load properly. This is why code splitting and lazy loading is extremely useful. It is also extremely useful from an accessibility perspective because it gives live regions time to fully render and therefore giving the screen reader time to catch-up.

>Vue lazy loaded component
```js
<template>
  <div class="container"> 
    <lazy-Live />
  </div>
</template>

<script>
export default {
  components: {
    lazyLive: () => import('ToastAnnouncement.vue')
  }
}
)
```

If you are using React, you can also lazy load components in tandem with Suspense. Suspense accepts a fallback component which allows you to display any React component as a loading state. 

>React lazy loaded component with suspense
```js
import React, { lazy, Suspense } from 'react';

const ToastAnnouncement = lazy(() => import('./ToastAnnouncement'));

const loader = () => <p>Please wait...</p>;

const Homepage = () => (
<div>
  <Suspense fallback={loader()}>
    <ToastAnnouncement />
  </Suspense>
</div>
)
```

## Open Source Libraries

Open source libraries are another great solution for fixing aria-live issues in JavaScript frameworks. They are quick and very easy to setup within your application. 

Most solutions in these packages are similar to the previous sections solution, where the aria-live region is on the page the whole time, and it switches out what is announced, Or it makes use of lazy loading.  

Here is a list of known live region node packages by framework: 


### React

  * [React-Aria-Live] (https://www.npmjs.com/package/react-aria-live)
  * [React-A11y-Announcer](https://github.com/thinkcompany/react-a11y-announcer)

### Angular

  * [Angular Material Live Announcer] (https://material.angular.io/cdk/a11y/overview#liveannouncer)

### Vue

  * [Vue-A11y-Utils] (https://jinjiang.dev/vue-a11y-utils/#vuelive-component)
 
## In Summary

When dealing with aria-live regions in JavaScript frameworks it can be tricky to ensure the regions are announcing properly. However, using any of these above methods will greatly improve the accessibility of your live regions in your JavaScript application!