Page Titles and A11y in Single Page Applications (esp. React & Vue)
Tags: a11y, webdev, react, vue
Published: 2019-09-16 05:45:19

(A version of this post which only detailed a React implementation was originally posted on [Up Your A11y: Handling Page Titles in React](https://www.upyoura11y.com/page-titles/))

## Why is the page title important for accessibility?

The short answer to this is that the page title is immediately available to a user without entering or navigating your page content. To get a feel for the accessibility implication of this, try turning on your screen reader now (If you're using a Mac, Cmd + F5 will toggle VoiceOver on and off). 

You should find that the title of this page is immediately announced to you, along with any other relevant browser information. If you have other tabs open, try tabbing or clicking through them and see how useful the titles are in understanding whether that tab contains the content you are looking for.

It’s clear that a concise, descriptive page title can be vital in surfacing your content to screen reader users.

## How to title your pages

W3C has some excellent [simple tips](https://www.w3.org/WAI/WCAG21/Techniques/general/G88.html) on this, which are summarised below.

**The title of each web page should:**

- Identify the subject of the web page
- Make sense when read out of context, for example by a screen reader, in a site map or list of search results
- Be short

**It may also be helpful for the title to:**

- Identify the site or other resource to which the web page belongs
- Be unique within the site or other resource to which the web page belongs

It’s also usually preferred that the most important/specific information comes first, e.g.

> Page Titles in Single Page Applications: DEV Community

Rather than:

> DEV Community: Page Titles in Single Page Applications

## Page titles and Single Page Applications

In Single Page Applications (such as React and client-side-rendered Vue apps), the page title never changes unless it is specifically managed. This leaves your users with few clues to the page that they’re currently viewing without entering and reading your content. The great news though is there are simple ways to manage the title easily.

## Managing the page title in React

For React apps we can simply implement the [React Document Title](https://github.com/gaearon/react-document-title) component.

For each page in your app, simply wrap the rendered components in the DocumentTitle component, and pass in the page title, e.g.

```jsx
class ExamplePage extends React.Component {
  render() {
    return (
      <DocumentTitle title="Example Title: Example Website Name">
        <main>
          ...
        </main>
      </DocumentTitle>
    );
  }
}
```

You can even tie the page title to a property in your component’s state if need be, e.g. if you need to load the page title from an API or elsewhere when the component mounts.

```jsx
class ExamplePage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      pageTitle: 'Loading Topics: Example Website Name',
    }
  }

  componentDidMount() {
    // Complete any tasks you need to complete before 
    // establishing page title

    this.setState({ pageTitle: 'Topics: Example Website Name' });
  }

  render() {
    const { pageTitle } = this.state;
    return (
      <DocumentTitle title={pageTitle}>
        <main>
          ...
        </main>
      </DocumentTitle>
    );
  }
}
```

## Managing the page title in Vue

Using Vue-Router you can add a simple hook to manage the page title each time the router location is changed. First, you'll need to configure the page titles for each of your routes in the meta data, for example:

```js
{
  path: '/',
  name: 'Home',
  meta: { 
    title: 'Home: MyApp',
  }, 
}
```

If the page title depends on some information in the route itself, this can be amended to:

```js
{
  path: '/',
  name: 'Home',
  meta: { 
    title: route => { 
      /* return custom title based on route/store/whatever  */ 
    },
  }, 
}
```

Now you have your page titles configured, we just need to add some code to the vue-router to make sure the title is updated after the route has changed.

This can be done by defining an afterEach action for the router, as so:

```js
router.afterEach((to, from) => {
  Vue.nextTick(() => {
    document.title = to.meta.title(to)
  })
})
```

Note that `Vue.nextTick()` is used, rather than setting the page title directly in the afterEach callback. This is to make sure that the page title is only updated after the router navigation is complete (including updating the browser history), thereby ensuring that your browser history stays in step with the page title.

## Simple and effective

I've detailed some basic implementations for two popular frameworks here, but feel free to comment below if you have an implementation for another Single Page App framework! 

As you can see above, the steps to implement page title management can be very simple, but the impact of doing so is substantial. Well named page titles will help a whole range of users browse your apps, as well as giving your pages a professional look and feel.

--------
*Did you find this post useful? Please consider [buying me a coffee](https://www.buymeacoffee.com/mgkZuRU) so I can keep making content* 🙂