Open6

PWA のインストールを最大限に活用する方法

@1000ch@1000ch

そもそもなぜアプリをインストールさせたいのか?

  • ホーム画面に常駐してもらうことで長期的にリテンションしたい
  • プッシュ通知を受信してもらいたい
  • ホーム画面からのショートカットコマンドを提供したい
  • URL をフックしアプリ起動して欲しい
@1000ch@1000ch

PWA のショートカット機能の定義

Get things done quickly with app shortcuts

Web App Manifest の shortcuts プロパティで、アプリのショートカットを定義できる。実行するコマンドには URL を指定する。

manifest.json
{
  "shortcuts": [
    {
      "name": "Open Play Later",
      "short_name": "Play Later",
      "description": "View the list of podcasts you saved for later",
      "url": "/play-later?utm_source=homescreen",
      "icons": [{ "src": "/icons/play-later.png", "sizes": "192x192" }]
    },
    {
      "name": "View Subscriptions",
      "short_name": "Subscriptions",
      "description": "View the list of podcasts you listen to",
      "url": "/subscriptions?utm_source=homescreen",
      "icons": [{ "src": "/icons/subscriptions.png", "sizes": "192x192" }]
    }
  ]
}
@1000ch@1000ch

PWA でのシェア機能の実装

Integrate with the OS sharing UI with the Web Share API

Web Share API で OS が提供する UI を呼び出せる。

if (navigator.share) {
  navigator.share({
    title: 'web.dev',
    text: 'Check out web.dev.',
    url: 'https://web.dev/',
  })
  .then(() => console.log('Successful share'))
  .catch((error) => console.log('Error sharing', error));
}

また、テキスト text やタイトル title や URL だけでなく、ファイルもシェアできる。

if (navigator.canShare && navigator.canShare({ files: filesArray })) {
  navigator.share({
    files: filesArray,
    title: 'Vacation Pictures',
    text: 'Photos from September 27 to October 14.',
  })
  .then(() => console.log('Share was successful.'))
  .catch((error) => console.log('Sharing failed', error));
} else {
  console.log(`Your system doesn't support sharing files.`);
}

PWA によるシェアされたデータのハンドリング

Receiving shared data with the Web Share Target API

Web App Manifest の share_target プロパティで、その PWA でどういったデータを受け取れるかを指定できる。

manifest.json
{
  "share_target": {
    "action": "/share-target/",
    "method": "GET",
    "params": {
      "title": "title",
      "text": "text",
      "url": "url"
    }
  }
}

PWA によるファイルのハンドリング

Let installed web applications be file handlers

PWA でファイルを受け取る際の挙動を実装できる。PWA でファイルをハンドリングしたい場合、

  1. Web App Manifest の file_handlers プロパティに、どんなファイルをどの URL でハンドリングするのかを定義する
  2. 定義した URL に対応する画面で、実際に受け取ったファイルをどのようにハンドリングするのかを実装する
manifest.json
{
  "file_handlers": [
    {
      "action": "/open-csv",
      "accept": {
        "text/csv": [".csv"]
      },
      "icons": [
        {
          "src": "csv-icon.png",
          "sizes": "256x256",
          "type": "image/png"
        }
      ],
      "launch_type": "single-client"
    }
  ]
}
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  launchQueue.setConsumer((launchParams) => {
    // Nothing to do when the queue is empty.
    if (!launchParams.files.length) {
      return;
    }

    for (const fileHandle of launchParams.files) {
      // Handle the file.
    }
  });
}
@1000ch@1000ch

PWA のプッシュ通知とアプリバッジ

Push notifications overview

Service Worker の push イベントをハンドリングし、プッシュ通知のサーバーに関する設定を Web App Manifest に定義することで、PWA にプッシュ通知を送信できる。

Badging for app icons

Badging API を使って PWA にバッジを表示可能で、Web Push と組み合わせて利用できる。

// Set the badge
const unreadCount = 24;
navigator.setAppBadge(unreadCount).catch((error) => {
  // Do something with the error.
});

// Clear the badge
navigator.clearAppBadge().catch((error) => {
  // Do something with the error.
});
@1000ch@1000ch

PWA のウィンドウ UI のカスタマイズ

Customize the window controls overlay of your PWA's title bar

ブラウザではタブや表示しているページのタイトルが表示されているが、オーバーレイ UI を Web App Manifest と HTML と CSS で実装することで、PWA のタイトルバーをカスタマイズできる。

  1. Web App Manifest の display_override プロパティに、ウィンドウの UI を上書きするかを定義する
  2. タイトルバーのスタイリングに必要な HTML と CSS を実装する
manifest.json
{
  "display_override": ["window-controls-overlay"]
}
<div class="search">
  <img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
  <label>
    <input type="search" />
    Search words in articles
  </label>
</div>
.search {
  /* Make sure the `div` stays there, even when scrolling. */
  position: fixed;
  /**
   * Gradient, because why not. Endless opportunities.
   * The gradient ends in `#36c`, which happens to be the app's
   * `<meta name="theme-color" content="#36c">`.
   */
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
  /* Use the environment variable for the left anchoring with a fallback. */
  left: env(titlebar-area-x, 0);
  /* Use the environment variable for the top anchoring with a fallback. */
  top: env(titlebar-area-y, 0);
  /* Use the environment variable for setting the width with a fallback. */
  width: env(titlebar-area-width, 100%);
  /* Use the environment variable for setting the height with a fallback. */
  height: env(titlebar-area-height, 33px);
}
@1000ch@1000ch

PWA のインストールステップ

Richer PWA installation UI - Chrome Developers

以前のようなシンプルなインストールダイアログを改善し、Web App Manifest の screenshots プロパティにスクリーンショットを定義することで、インストール時に表示できるようになった。

manifest.json
{
  "screenshots": [
    {
      "src": "source/image1.gif",
      "sizes": "320x640",
      "type": "image/gif"
    }
  ]
}

How to provide your own in-app install experience

また、インストールプロンプトの表示を、ユーザーが最もエンゲージされている状況など、適切なタイミングで表示できるようにカスタマイズする。デフォルトではブラウザの実装に応じて自動で表示されるが、 Window の beforeinstallprompt イベントをハンドリングすることで、任意のタイミングで表示するように実装できる。

// Initialize deferredPrompt for use later to show browser install prompt.
let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent the mini-infobar from appearing on mobile
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;
  // Update UI notify the user they can install the PWA
  showInstallPromotion();
  // Optionally, send analytics event that PWA install promo was shown.
  console.log(`'beforeinstallprompt' event was fired.`);
});

また、PWA がインストールされた場合を Window の appinstalled イベントでハンドリングできる。

window.addEventListener('appinstalled', () => {
  // Hide the app-provided install promotion
  hideInstallPromotion();
  // Clear the deferredPrompt so it can be garbage collected
  deferredPrompt = null;
  // Optionally, send analytics event to indicate successful install
  console.log('PWA was installed');
});