How to Web-Accessibility Page-Title

Web Accessibility – Essential for Some, Useful for All

W3C

The html title attribute is used to give users a feedback where they are. The title is shown in the browser tab, sometimes used as headline for the browser window and announced by screenreaders. In addition bookmarks and search results are using the page title to present it to users . A good title is necessary to know which tab to choose and for screenreader users to know where they are currently. But what makes a good title?

  • The current location is in the front and the page title afterwards
    • Home – Martin Forstner’s Blog
    • Work – Martin Forstner’s Blog
  • It is consistent over the whole eco-system (usually your homepage)
  • It changes on every site change. For example if a link is resolved

Example in Google Chrome from my Blog

HTML Example

				
					<html><head>
    <title>Home - Martin Forstner's Blog
    </title>
</head></html>
				
			

Angular Example

In Angular it is usually done by importing the Title from @angular/platform-browser. But this is very annoying if you have more than 1 Sit, because therefore you have to set in every component the title manually. I will show you an example with the angular common router.

app.component.ts

In the app.component you are subscribing to NavigationEnd events and furthermore setting the title for every route. The while loop is needed for lazy loaded routes!

				
					import { Component, OnInit, VERSION } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { filter, map } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular ' + VERSION.major;

  constructor(
    private title: Title,
    private router: Router,
    private activatedRoute: ActivatedRoute
  ) {}

  ngOnInit() {
    this.router.events
      .pipe(
        filter((e) => e instanceof NavigationEnd),
        map(() => {
          let child = this.activatedRoute.firstChild;
          while (child) {
            if (child.firstChild) {
              child = child.firstChild;
            } else if (child.snapshot.data && child.snapshot.data['title']) {
              return child.snapshot.data['title'];
            } else {
              return 'No Title up to now';
            }
          }
        })
      )
      .subscribe((title) => {
        this.title.setTitle(title + ' - TestTitle Example');
      });
  }
}

				
			

app.routing.module

Just for example routes. Could be done in any routing.module or lazy laoded feature module

				
					import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HelloComponent } from './hello.component';

const routes: Routes = [
  {
    path: '',
    component: HelloComponent,
    data: { title: 'Home' },
  },
  {
    path: 'lazy',
    loadChildren: () => import('./lazy-loaded/lazy-loaded.module').then(m =>m.LazyLoadedModule),
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

				
			

Full example @Stackblitz

No Comments

You can be the first one to leave a comment.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.