Language in URL with HTML lang attribute and FastBoot

Our site specifies the language for a page in the URL - http://oursite/en/whatever. I am using a route to pick this up and set the locale to use for the content. We even perform substitutions, so that http://oursite/zh/whatever behaves like (or redirects to) http://oursite/cn/whatever. So far so good.

However, there are a few things that are needed for SEO and accessibility that aren’t in the rendered body content:

  1. The lang attribute on the html tag: <html lang=“zh”>
  2. The description meta, which should be in localized text, preferably pulled from our ember-i18n strings.
  3. The rel=canonical, which needs to specify the URL with cn rather than zh, etc.

From what I’ve read, ember-cli-head should be perfect for the latter two. However, what’s the right way to set the language in the html tag? I can backfill it from my route, but will screen readers be able to adjust if the page language adjusts after the initially rendered page? Is there something I can use with fastboot so the page always renders with the html lang attribute tracking the ISO language corresponding to the language from the URL? I can’t DOM-hack from fastboot…

Thanks for the detailed writeup! It made me go in search of (what I thought was) a “long closed issue” in the ember-cli-fastboot repo. Turns out that I had completely dropped the ball and missed the PR that added this functionality! :man_facepalming:

I just merged this PR, which adds the ability for <html> attributes to be set:

https://github.com/ember-fastboot/fastboot/pull/180

Sooo, you should now be able to do what you need here (assuming fastboot@1.2.0 or higher is in use).

2 Likes

What’s the best way to apply fastboot@1.2.0? ember-cli-fastboot resolves to use 1.1.2 on my project. Add it as a dev-dependency? A dependency? Or a resolution?

I presume you are using yarn? You can either do a yarn upgrade or specify a resolution.

Since we know we are using relatively recent Ember, for the reference of anybody else who needs to do this, here is the code we are using in the afterModel hook of the route that provided the locale:

        const docService = getOwner(this).lookup('service:-document');
        if (docService) {
            docService.documentElement.setAttribute('lang',this.get('siteconfig.IsoLocale'));
        }

Note that docService.documentElement.lang = this.get('siteconfig.IsoLocale'); did not give an error but also did not work except in the browser.