Adding dynamic iOS app banner meta tag in Angular


When dynamically adding a iOS app banner meta tag to an Angular 10 app, I can see that the tag is indeed added under the head tag, but Safari on iOS never shows the app banner. I suspect that this may have something to do with the page’s head already having been parsed by Safari, before the meta tag is added.

When I say dynamically, it’s because I only want to show the app banner on certain routes of the Angular app. If I add the meta tag manually in the index.html page, then the banner appears as expected.

This is an example of what an iOS app banner tag looks like: <meta name="apple-itunes-app" content="app-id=12345">

The way that I have been able to add the meta tag is by creating a resolver service:

 import { Injectable } from '@angular/core';
 import { Resolve } from '@angular/router';
 import { Observable, of } from 'rxjs';
 import { Meta } from "@angular/platform-browser";

 @Injectable({
   providedIn: 'root'
 })

 export class MobileAppBannerResolveService implements Resolve<Observable<string>> {
   constructor(
     private metaService: Meta
   ) {}

   resolve(): Observable<string> {
     this.metaService.addTag({ name: 'apple-itunes-app', content: 'app-id=12345' });
     return of(null);
   }

   // Remove the `meta` tag from the HTML page
   cleanup(): void {
     this.metaService.removeTag("name="apple-itunes-app"");
   }
 }

I add this resolver in the Route (here’s an example snippet):

  {
    path: 'charts',
    component: ChartComponent,
    children: chartRoutes,
    resolve: {
        mobileApp: MobileAppBannerResolveService
    }
  }

And then include it in the component, via the constructor:

 constructor(
    public activatedRoute: ActivatedRoute,
    private router: Router,
    private mobileAppBannerResolveService: MobileAppBannerResolveService
   ) {}

At this point, the meta tag is added by virtue of the service’s resolve() method.

Finally, when leaving that page, I remove the tag in the ngOnDestroy:

   ngOnDestroy(): void {
     this.mobileAppBannerResolveService.cleanup();
   }

Is it possible to do what I’m trying to do? Or do I just need to include the tag in the index.html and have it be in every route in the Angular app? I did have a look to see if there were any hooks in navigation that were early in the lifecycle, but to no avail. e.g. I tried NavigationEnd.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img