Accessible page titles in a Single Page App

Published 19 July 2018 category: thoughts

According to WCAG 2.4.2 pages should have titles. How to go about this in a single page world?

What are titles for?

Pages have titles so that people can recognise where they are. They are like a plaquette on a meeting room door, signposts that mark the platform in a train station or the signage for a supermarket aisle. They help people figure out where they are.

Additionally, page titles also signify uniquely what’s on a URL. This is helpful for search engines, they display the title. Or for social media platforms, they display it when you share a link. People using screenreaders hear the title, it lets them figure out what a page is when they land on it.

Titling pages, the traditional way

In a site with multiple pages, you can put different content in the <title> element for each different page. This is trivial if you build each page separately, it is a little more work when the value comes out of a CMS, but still fairly straightforward.

Titling pages in Single Page Apps

In a Single Page App (SPA), the user never leaves the page. There is no new page with a new title. Instead, you’ll have to update this manually by changing the value or document.title, which is where the page title is in the DOM.

Changing pages in SPAs is often done with routers like react-router and vue-router. I was surprised to see that, by default, those two only update content and the URL, not the document title.

You can update the page title manually, though. In React, you can do it in the componentDidMount() of a route, and there is a react-document-title package that does it for you. If you want to update more meta info than just the title, there is React Helmet.

In Vue, I had luck doing it in beforeEach of the router:

router.beforeEach((to, from, next) => {
  document.title = `${} - Your site`;

But if you’d like to abstract this further and update the page’s title along with other things in the head of your document, there is Vue Helmet or Vue Meta.

(Update 2 June 2020) In Svelte, you can set page titles using the special <svelte:head> element in the components that you use as a route, like so:

<!-- MyPage.svelte -->
  <title>Page Title goes here</title>

Announcing titles

In screenreaders, when a user goes to a new page, it will read out the title of that page. In a Single Page App world, you can update the title with document.title, but, sadly, that change does not trigger a screenreader announcement. It is helpful to do this manually, for example by putting content into a live region (the on demand live region abstracts this).

There are different strategies as to what to read out on a route. In an SPA, you could choose to set focus to the top of the document when you do a route, this would make it feel like a multi page application. Users would have to use skip links to get back to the content, just like in multi page applications. But maybe you only update one section, and your strategy is to move focus to the new content. In this case, you could ensure the title of whatever is new is read out, rather than the updated page title. For example, if you replace the main by something new and then focus the new content, convey to assistive technologies what the title of the newly focused content is, for example by having its first heading announced.

Does this mean the title is irrelevant in SPAs? Not really, it is still useful to have an up to date title, for example for people switch between tabs or when you turn on Server Side Rendering.


Giving pages unique titles aids accessibility and is compulsory if you are after WCAG 2 AA compliance. If you build a single page app, update the title manually, but also look at having something useful announced when new content is inserted. It could make more sense for this to be a section title than the document’s title, depending on what you’re building.

Thanks Job, Almero and Marco for answering questions and giving early feedback.

Update 2 June 2020: added info for Svelte

Comments & mentions (19)

Xan 20 Jul 2018 13:29:00

Here’s how you can actually fix page titles in Vue. The above code snippet is both broken and missing an essential line.

router.beforeEach((to, from, next) => { document.title = `${} – Your site name`;

next(); });

Without next() your routes will never change, also the snippet in the article is broken syntax.

Aarón 22 Jul 2018 10:31:00

Hi! Nice article :D

Regarding “But maybe you only update one section, and your strategy is to move focus to the new content.” it’s worth to take a look at Reach Router for React, by Ryan Florence, which moves focus automatically to the new content loaded by a route.

Christopher Lane 31 Oct 2018 22:14:00

Thanks. I was wondering if titles are irrelevant in SPAs since screen reader don’t announce. Now I know they still are.

Daniel Nixon 29 Apr 2019 01:14:34

Nice post. This is something I’m trying to solve in a generic way over at I don’t have a Vue implementation yet but it’s on my list (

Paul Foster likes this
Anselm Hannemann likes this
Suzanne Aitchison likes this
Bram Willemse reposted this replied: “Accessible page titles in a Single Page App”…
Charles Schmidt replied:…
Ben Robertson replied: Accessible page titles in a Single Page App…
Refresh Detroit replied: Accessible page titles in a Single Page App… #a11y #accessibility
UXAustralia replied: Accessible page titles in a Single Page App (Hidde de Vries)… #a11y #design
Michael Sylvie replied: @abdelmaseh since SPAs are near and dear to our hearts…
:masuP9: replied: 見てる。遷移後にページ先頭じゃなくてコンテンツの先頭にフォーカス当てるのどうなんだろうなー感はある / Accessible page titles in a Single Page App…
Suzanne Aitchison replied: Yep you're right, they're separate but related issues. I wrote a bit about handling route changes that covers this (the example is in React but the principle is universal) - basically I would focus on the new H1…
Suzanne Aitchison replied: it looks like you reached a similar conclusion in your post too ????
Hidde replied: thanks for the link, that's a great post, love how you explained it!
Suzanne Aitchison replied: Thanks! I have a little site of A11y tutorials - I'm pretty sure I have actually quoted you somewhere in there ????????
Leave a comment
Posted a response to this?

This website uses Webmentions. You can manually notify me if you have posted a response, by entering the URL below.