Prog blog

How to use Web Share API in mobile Angular application

How to use Web Share API in mobile Angular application

For some time now, mobile browsers have been able to use the native share option from operating systems, as we usually see in mobile applications.

According to Can I use, 49% of browsers already have this option available and the popularity will grow in the coming years.

Can i use - web share API screenshot

Source: Web Share API - Can i use

An example of a video how the share button in my blog works.

We start creating the button by creating a share-button component. In it we will call Share API window.navigator.share after clicking the button.

ng generate component share-button --module=app

Share button

share-button.component.ts

import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

export interface Share {
  title?: string;
  text?: string;
  url?: string;
}

interface ExtendNavigator extends Navigator {
  share: (share: Share) => Promise<void>;
}

interface ExtendWindow extends Window {
  navigator: ExtendNavigator;
}

declare var window: ExtendWindow;

@Component({
  selector: 'app-share-button',
  templateUrl: './share-button.component.html',
  styleUrls: ['./share-button.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShareButtonComponent {
  @Input() share: Share;

  onClick() {
    window.navigator.share(this.share);
  }
}

Input share will accept the data we want to share. Possible fields are title, text and url. At least one of these fields is required.

For faster design. Share button uses finished components from angular material design library (rounded button and share icon).

share-button.component.html

<button
  mat-fab
  color="primary"
  class="share-button"
  aria-label="share button with a share icon"
  (click)="onClick()"
>
  <mat-icon>share</mat-icon>
</button>

Then you need to display button for each post you create.

In my blog post is observable, which emits data after loading it with xhr. Additionally I added isPlatformBrowser to prevent prerender from returning errors and I check if web share API exists in the browser. The text sent by the share API is the link, the blog name, the post title and the address where the post can be found.

post.component.ts

  share$ = this.post$.pipe(
    filter(() => isPlatformBrowser(this.platformId)),
    filter(() => 'share' in navigator),
    map(post => {
      return {
        title: environment.siteName,
        text: post.meta.title,
        url: `${environment.baseUrl}/${post.id}`,
      } as Share;
    })
  );

The last step is to insert our HTML button together with a message for share button.

post.component.html

<ng-container *ngIf="share$ | async as share">
  <app-share-button [share]="share"></app-share-button>
</ng-container>