同じドメイン名を利用して複数の PWA を構築し、同じ組織またはサービスに属していることをユーザーに認識させる方法。
Demian は、マルチオリジン サイトのプログレッシブ ウェブアプリに関するブログ投稿で、複数のオリジンをベースとするサイトが 1 つのプログレッシブ ウェブアプリを構築する際に直面する課題について解説しています。
このようなサイト アーキテクチャの例として、次のような e コマース サイトがあります。
- ホームページは
https://www.example.com
にあります。 - カテゴリページは
https://category.example.com
でホストされています。 https://product.example.com
の商品詳細ページ。
この記事で説明したように、同一オリジン ポリシーには複数の制限があるため、Service Worker、キャッシュ、権限をオリジン間で共有できません。そのため、このような構成は避け、すでにこの方法で構築されているサイトがある場合は、可能な限り単一のオリジン サイト アーキテクチャへの移行を検討することを強くおすすめします。
この投稿では、その逆のケースについて見ていきます。異なるオリジンに対して単一の PWA を使用するのではなく、同じドメイン名を利用して複数の PWA を提供する場合を分析し、それらの PWA が同じ組織またはサービスに属していることをユーザーに認識させます。
お気づきのように、ここで使用する用語は異なりますが、ドメインやオリジンなど、相互に関連しています。先に進む前に、これらのコンセプトを確認しておきましょう。
技術用語
- ドメイン: ドメイン ネーム システム(DNS)で定義されているラベルのシーケンス。たとえば、
com
とexample.com
はドメインです。 - ホスト名: 少なくとも 1 つの IP アドレスに解決される DNS エントリ。たとえば、
www.example.com
はホスト名、example.com
は IP アドレスがあればホスト名になります。com
は IP アドレスに解決されないため、ホスト名にはできません。 - 生成元: スキーム、ホスト名、ポート(オプション)の組み合わせ。たとえば、
https://www.example.com:443
はオリジンです。
その名前が示すように、同一オリジン ポリシーではオリジンに制限が課されるため、この記事では「同一オリジン」という用語を使用します。ただし、さまざまな「オリジン」を作成するために、「ドメイン」または「サブドメイン」を使用して、使用する手法を説明することがあります。
関連する複数の PWA がある場合
場合によっては、独立したアプリを構築しても、それらを同じ組織または「ブランド」に属するものとして識別したいことがあります。同じドメイン名を再利用すると、このような関係を確立できます。次に例を示します。
- ある e コマースサイトでは、ユーザーが商品を購入するメインのウェブサイトに属することを理解しつつ、販売者が在庫を管理できるようにスタンドアロンのエクスペリエンスを構築したいと考えています。
- あるスポーツ ニュースサイトでは、主要なスポーツ イベント専用のアプリを作成し、ユーザーがお気に入りの試合に関するデータを通知で受信できるようにするとともに、プログレッシブ ウェブアプリとしてインストールし、ニュース会社が開発したアプリであることをユーザーに認識させたいと考えています。
- ある会社が、個別のチャットアプリ、メールアプリ、カレンダー アプリを作成し、会社名に関連付けられた個別のアプリとして動作させたいと考えています。
別のオリジンの使用
このような場合に推奨されるアプローチは、概念的に異なるアプリごとに固有のオリジンを持つことです。
すべてのサービス内で同じドメイン名を使用する場合は、サブドメインを使用します。たとえば、複数のインターネット アプリやサービスを提供している企業は、メールアプリを https://mail.example.com
で、カレンダー アプリを https://calendar.example.com
でホストし、ビジネスのメインのサービスを https://www.example.com
で提供できます。別の例として、重要なスポーツ イベント(https://footballcup.example.com
でのサッカーのチャンピオンシップなど)に特化した独立したアプリを作成するスポーツサイトの場合、ユーザーは https://www.example.com
でホストされているメインのスポーツサイトとは別にインストールして使用できます。このアプローチは、顧客が会社のブランドで独自のアプリを作成できるプラットフォームでも有用です。たとえば、販売者が https://merchant1.example.com
や https://merchant2.example.com
などで独自の PWA を作成できるアプリなどです。
異なるオリジンを使用することでアプリ間の分離が保証されます。つまり、それぞれが以下のような異なるブラウザ機能を個別に管理できます。
- インストール可能性: アプリごとに独自のマニフェストがあり、インストール可能な独自のエクスペリエンスが提供されています。
- ストレージ: 各アプリには独自のキャッシュ、ローカル ストレージのほか、基本的にはあらゆる形式のデバイスのローカル ストレージがあり、他のアプリと共有されることはありません。
- Service Worker: 各アプリには、登録されたスコープに対応する独自の Service Worker があります。
- 権限: 権限のスコープも生成元です。これにより、ユーザーはどのサービスに対して権限を付与しているのかを正確に把握でき、通知などの機能が各アプリに適切に関連付けられます。
独立した複数の PWA を使用する場合、このような分離を行うことが最も望ましいため、この方法を強くおすすめします。
サブドメイン上のアプリが互いにローカルデータを共有する必要がある場合は、引き続き Cookie を使用してローカルデータを共有できます。また、より高度なシナリオでは、サーバーを介したストレージの同期を検討することもできます。
同じオリジンを使用
2 つ目の方法では、異なる PWA を同じオリジンで構築します。これには、次のシナリオが含まれます。
重複しない経路
同じオリジンにホストされ、パスが重複しない複数の PWA または概念的な「ウェブアプリ」。次に例を示します。
https://example.com/app1/
https://example.com/app2/
パスの重複/ネストされたパス
同じオリジンに複数の PWA があり、一方のスコープがもう一方のスコープ内にネストされている場合:
https://example.com/
(「外部アプリ」)https://example.com/app/
(「内部アプリ」)
Service Worker API とマニフェスト形式では、パスレベルのスコープを使用して、上記のいずれかを行うことができます。ただし、どちらの場合も、同じオリジンを使用すると多くの問題と制限が生じます。ブラウザがこれらを個別の「アプリ」と完全にはみなさないことが根本原因であるため、このアプローチはおすすめしません。
次のセクションでは、これらの課題について詳しく説明します。また、別々の送信元を使用することができない場合に何ができるかを分析します。
同一オリジンの複数の PWA の課題
以下に、同一オリジン アプローチに共通する実践的な問題をいくつか示します。
- ストレージ: Cookie、ローカル ストレージ、あらゆる形式のデバイスのローカル ストレージは、アプリ間で共有されます。このため、ユーザーが 1 つのアプリのローカルデータをワイプすると、元のデータがすべてワイプされます。1 つのアプリに対してこれを行う方法はありません。Chrome や他の一部のブラウザでは、いずれかのアプリをアンインストールする際に、ローカルデータのワイプを積極的にユーザーに促します。これは、元の他のアプリのデータにも影響します。もう 1 つの問題は、アプリが保存容量を共有する必要があることです。つまり、どちらかが占有する容量が多すぎると、もう一方が悪影響を受けます。
- 権限: 権限はオリジンに関連付けられています。つまり、ユーザーが 1 つのアプリに権限を付与すると、そのオリジンのすべてのアプリに同時に権限が適用されます。これは良いことのように思えるかもしれませんが(権限を複数回要求する必要はありません)、ユーザーが 1 つのアプリに対する権限をブロックすると、他のアプリがその権限をリクエストしたり、その機能を利用したりできなくなることを覚えておいてください。
- ユーザー設定: 設定もオリジンごとに設定されます。たとえば、2 つのアプリでフォントサイズが異なる場合、一方のアプリで補正するために一方のみを拡大調整する場合、もう一方のアプリにもその設定を適用しないと調整できません。
このような課題があるため、このアプローチを推進するのは困難です。ただし、別々のオリジンの使用セクションで説明したように、別のオリジン(サブドメインなど)を使用できない場合は、前述の 2 つの同一オリジン オプションから、パスの重複やネストされたパスではなく、重複しないパスを使用することを強くおすすめします。
前述のように、このセクションで説明する課題は、同じオリジンのアプローチに共通です。次のセクションでは パスの重複やネストの 使用が推奨されない方法について詳しく説明します
パスの重複やネストに関するその他の課題
パスが重複/ネストされている場合(https://example.com/
が外側のアプリ、https://example.com/app/
が内側のアプリ)では、内部アプリ内のすべての URL が、実際には外側アプリと内部アプリの両方の一部と見なされるという問題があります。
実際には、次のような問題が発生します。
- インストール プロモーション: ユーザーが内部アプリを(ウェブブラウザなどで)訪問した場合、外部アプリがすでにユーザーのデバイスにインストールされていれば、ブラウザにはインストール プロモーション バナーが表示されず、BeforeInstallPrompt イベントはトリガーされません。その理由は、現在のページがすでにインストールされているアプリに属しているかどうかをブラウザが確認して、そのアプリに属していると判断するためです。これを回避するには、内部アプリを手動で([ショートカットを作成] ブラウザ メニュー オプションを介して)インストールするか、外部アプリよりも先に内部アプリをインストールします。
- 通知と Badging API: 外側のアプリはインストールされているが、内側のアプリはインストールされていない場合、内側のアプリからの通知とバッジは、外側のアプリ(インストール済みのアプリの最も近接するスコープ)に誤って帰属します。この機能は、ユーザーのデバイスに両方のアプリがインストールされている場合に適切に機能します。
- リンク キャプチャ: 外部アプリが内部アプリに属する URL をキャプチャする場合があります。これは、外部アプリはインストールされているが、内部アプリはインストールされていない場合に特に当てはまります。同様に、内部アプリにリンクする外部アプリ内のリンクは、外部アプリのスコープ内にあるとみなされるため、内部アプリにキャプチャをリンクしません。また、ChromeOS と Android では、これらのアプリが Google Play ストアに(Trusted Web Activity として)追加されている場合、外側のアプリがすべてのリンクをキャプチャします。内部アプリがインストールされている場合でも、OS はユーザーに外部アプリで開くかどうかの選択肢を提供します。
おわりに
この記事では、デベロッパーが同じドメイン内で相互に関連のある複数のプログレッシブ ウェブアプリを作成するさまざまな方法について説明しました。
まとめると、独立した PWA をホストするには、別のオリジン(サブドメインを使用するなど)を使用することを強くおすすめします。同じオリジンでホストする場合、ブラウザはこれらを完全には別アプリとはみなさないため、多くの課題があります。
- 別のオリジン: 推奨
- オリジンが同じで、パスが重複していない: 非推奨
- 同一オリジン、重複/ネストされたパス: 非推奨
重複しないパス(https://example.com/app1/
と https://example.com/app2/
など)を使用して異なるオリジンを使用できない場合は、https://example.com/
(外側のアプリの場合)や https://example.com/app/
(内側のアプリの場合)のように、重複するパスやネストされたパスを使用するよりも強くおすすめします。
参考情報
技術レビューと提案に多大な感謝を申し上げます: Joe Medley、Dominick Ng、Alan Cutter、Daniel Murphy、Penny McLachlan、Thomas Steiner、Darwin Huang
写真撮影: Tim Mossholder、出典: Unsplash