PWAでユーザーごとのプロフィールページや商品ページをホーム画面へ追加したい。
そう考えたとき、多くの人が start_url にユーザーIDや商品IDを書こうとします。
実は私も最初はそう考えていました。
ところがPWA LABで実際に検証を重ねるうちに、それよりもシンプルで柔軟な方法があることに気付きました。
しかも、この方法ならMDNが推奨しているプライバシーへの配慮にも沿った設計になります。
start_urlにはユーザーIDを書かない方が良い
PWAでは、ホーム画面から起動したときに最初に開くページを start_url で指定できます。
例えばプロフィールページをホーム画面へ追加したい場合、次のように書きたくなるかもしれません。
{
"start_url": "/user/123"
}
一見すると問題なさそうですが、MDNではこのようにユーザーを一意に識別できる情報を start_url に含めることは推奨されていません。
理由は、ブラウザのデータを削除したあとでも、インストール済みのPWA情報からユーザーを識別できる可能性があり、プライバシー上の問題につながるためです。
そのため、start_url はできるだけ固定値や相対パスを利用することが推奨されています。
よくある実装の問題
多くのサイトでは次のような設定になっています。
{
"start_url": "/"
}
もちろんこれでも正常に動作します。
しかし問題は、ホーム画面へ追加した場所がどこだったとしても、起動時にはトップページへ戻ってしまうことです。
例えば次のようなケースです。
- ブログの記事
- ECサイトの商品ページ
- ユーザープロフィール
- ドキュメントの特定ページ
せっかく目的のページをホーム画面へ追加したのに、毎回トップページが開いてしまうのでは使い勝手が良いとは言えません。
👉 PWAの作り方|manifest.json・Service Worker・ホーム画面対応を丁寧に解説 の解説が役に立ちます。
解決方法は start_url: “.”
実はこの問題は非常にシンプルに解決できます。
{
"start_url": "."
}
これだけです。
. は現在のページを基準とした相対パスとして扱われます。
PWA LABでも何パターンも検証しましたが、特別な理由がない限り、この書き方が最も自然な挙動になりました。
この設定なら、
- 記事ページから追加 → 記事ページで起動
- 商品ページから追加 → 商品ページで起動
- プロフィールページから追加 → プロフィールページで起動
という期待通りの動作になります。
「ホーム画面に追加したページが、そのまま入口になる。」
PWAとして考えると、こちらの方が直感的です。
動的manifestとの相性も良い
ユーザーごとにmanifest.jsonを動的生成している場合でも、この方法は非常に相性が良くなります。
例えば次のようなmanifestです。
{
"name": "Example",
"start_url": "."
}
これならユーザーIDを start_url へ埋め込む必要はありません。
結果として、
- ユーザーを識別する情報を書かない
- 現在表示しているページをそのまま起動できる
- URL構造が変わっても柔軟に対応できる
という設計になります。
実際、Petalのようにユーザーごとのページをホーム画面へ追加する仕組みでも、この考え方は非常に扱いやすい構成でした。
ECサイトやブログでも活用できる
この方法はプロフィールページだけの話ではありません。
例えば、
- ブログの記事をホーム画面へ追加
- ECサイトの商品ページをホーム画面へ追加
- ドキュメントの特定ページをホーム画面へ追加
- イベントページをホーム画面へ追加
など、「今見ているページをそのままアプリの入口にしたい」ケース全般で活用できます。
多くのサービスでは start_url がトップページ固定になっているため、ホーム画面へ追加しても毎回トップへ戻されてしまいます。
start_url: "." を使えば、その違和感をなくすことができます。
注意点:Androidでは id と scope の設計も重要
start_url: "." を使えば、現在のページを起点にしてPWAを起動できます。
ただし、ユーザーごと・商品ごと・ページごとに複数のPWAをホーム画面へ追加したい場合は、Androidでは id と scope の設計にも注意が必要です。
例えば、
- ユーザーAのページ
- ユーザーBのページ
をそれぞれホーム画面へ追加した場合でも、共通の id や広すぎる scope を設定していると、Android側で同じアプリとして判定されることがあります。
その結果、
- 2つ目のインストールが表示されない
- すでにインストール済みと判断される
- 別のページなのに同一アプリへまとめられる
といった挙動になる場合があります。
私もPWA LABでこの問題にかなり時間を使いました。
最終的には、start_url だけではなく、id と scope を含めたアプリ識別全体を設計する必要があることが分かりました。
詳しい検証結果については、AndroidとiPhoneでmanifestを出し分けた理由をまとめた記事で詳しく解説しています。
まとめ
start_url にユーザーIDや商品IDなどを書かなくても、
{
"start_url": "."
}
を使えば、現在表示しているページをそのまま起点としてPWAを起動できます。
これはMDNが推奨するプライバシーへの配慮にも沿った設計でありながら、ユーザー体験も向上できる方法です。
ホーム画面に置きたいのが「サイト全体」ではなく「このページ」なら、まず試してみる価値があります。
PWA LABで実際に検証してみても、特別な理由がない限り start_url: "." がもっとも扱いやすく、今後も基本形として採用していく予定です。