iOSでホーム画面に追加したURLが勝手に変わる?原因と対策(PWA・manifestの罠)



当サイト、オリジナルWordPressプラグイン「OJapp PWA Marketing」を使用しています。

各記事は専用アイコンでホーム画面に追加できます。ぜひお試しください。

iPhoneでWebページをホーム画面に追加したとき、今見ていたページではなく、別のURLが保存されてしまうことがあります。

PetalまわりのPWA設定を見直していて、かなり分かりやすい罠にハマりました。

iPhoneであるページを開いて「ホーム画面に追加」したのに、追加したアイコンから開くと、さっき見ていたURLとは違うページに飛んでしまう。

最初はSafariのキャッシュか、iOSの謎挙動かと思いました。

でも、原因を追っていくと本質はもっとシンプルでした。

そのページを1つのアプリとして残したいのに、manifest.json がサイト全体アプリのような設計になっていた。

つまり、1S1Aと1P1Aの設計が混ざっていたんです。

この記事では、iOSでホーム画面に追加したURLが勝手に変わる原因を、start_url、scope、manifest設計の関係から整理します。

アッピン
この問題は「iOSが勝手に変なことをした」というより、manifest側で「起動したらこのURLを開いてね」と指示していた可能性が高いよ。

起きたこと:開いていたURLではなく、別のURLが起動した

今回やりたかったことは、かなり単純です。

ユーザーごとのページをホーム画面に追加して、次回もそのページを直接開けるようにしたかっただけです。

たとえば、次のようなイメージです。

  • /petal/user/?u=ojapp を開く
  • そのページをiPhoneのホーム画面に追加する
  • ホーム画面のアイコンから、同じページを開く

これなら、ユーザーは「今見ているページをホーム画面に残した」と感じます。

ところが実際には、ホーム画面のアイコンから開くと、別のURLへ飛んでしまいました。

つまり、ユーザーはAというページを追加したつもりなのに、起動するとBというページが開く状態です。

これは個人ページ、名刺ページ、商品ページ、予約ページのように、ページごとに意味があるサービスではかなり困ります。

原因は start_url にあった

PWAのmanifest.jsonには、start_url という項目があります。

これは、ホーム画面から起動したときに、最初に開くURLを指定するものです。

たとえば、次のように書いている場合です。

{
  "name": "Example App",
  "short_name": "Example",
  "display": "standalone",
  "start_url": "/app/"
}

この場合、ユーザーがどのページからホーム画面に追加しても、起動時に /app/ が開かれる可能性があります。

これ自体は間違いではありません。

むしろ、サイト全体を1つのアプリとして扱うなら自然です。

問題は、ページごとに別々の入口を作りたい場合です。

今見ているページをそのままホーム画面に残したいのに、manifest側で固定の start_url を指定していると、起動時にそのURLへ戻されます。

これが「ホーム画面に追加したURLが勝手に変わった」ように見える正体です。

1S1Aと1P1Aが混ざると事故る

今回の問題は、単なるURL指定ミスというより、PWAの設計思想のズレでした。

PWAには、大きく分けて2つの考え方があります。

  • 1S1A:One Site. One App. サイト全体を1つのアプリとして扱う
  • 1P1A:One Page. One App. 1ページを1つのアプリとして扱う

1S1Aでは、サイト全体が1つのアプリです。

どのページから追加しても、起動先はトップページやアプリ本体に戻る設計になりやすいです。

たとえば、ECサイト全体、管理画面、ニュースアプリ、会員サイトなどはこの考え方と相性がいいです。

一方で1P1Aでは、ページごとに別の入口を作ります。

商品ページ、記事ページ、プロフィールページ、名刺ページ、Webツールなどは、ページそのものに価値があります。

この場合は、開いているページをそのままホーム画面に残したい。

だから、固定の start_url でトップや別ページへ戻す設計とは相性が悪いです。

この違いについては、1P1A(One Page. One App.)というPWA設計思想でも詳しく書いています。

今回の罠:ページ保存型なのに、固定start_urlを書いていた

今回の失敗をかなり簡単に言うと、こうです。

1P1Aとして動かしたいページに、1S1Aっぽい固定start_urlを入れていた。

これです。

ページごとにホーム画面へ残したいなら、本来は「今開いているページ」が起動URLになるべきです。

でもmanifestに固定の start_url があると、ブラウザはそれを起動URLとして扱います。

その結果、iPhoneでホーム画面に追加したあと、アイコンをタップすると別のURLが開いてしまう。

ユーザーから見ると、URLが勝手に変わったように見えます。

でも実際には、manifestでそう指示していたわけです。

なぜiOSだと余計に分かりにくいのか

Android Chromeは、manifestの指定が比較的分かりやすく反映されます。

start_url、scope、display、theme_color なども、動きを見れば判断しやすいです。

一方でiPhone Safariは、manifestのすべてをAndroidと同じように扱うわけではありません。

効く項目もあれば、効いているのか分かりにくい項目もあります。

だから開発中に「iOSではこの設定は無視されているっぽいな」と思ってしまうことがあります。

でも、ある条件が揃った瞬間に、急にPWAらしい挙動が表に出ることがあります。

今回も、固定の start_url は前から入っていたのに、最初は問題として目立っていませんでした。

そこにmanifestやアイコンまわりの設定を触ったことで、起動URLのズレが表に出たように見えました。

こういうところが、iOS PWAのかなり面倒なところです。

「昨日まで動いていたのに、今日になって急に変わった」ように見える。

でも実際には、前から埋まっていたmanifestのミスが、別の変更をきっかけに見えるようになっただけだったりします。

対策:ページごとに残したいなら start_url は固定しない

ページごとにホーム画面へ追加させたいなら、まず start_url を見直します。

トップページへ戻したいPWAなら、固定URLでも問題ありません。

{
  "start_url": "/"
}

これは、サイト全体を1つのアプリとして扱う1S1A向きです。

でも、今開いているページをそのまま残したいなら、次のようにします。

{
  "start_url": "."
}

"." は、現在のページを基準にする指定です。

ページごとのホーム画面追加、つまり1P1Aでは、この形がかなり扱いやすいです。

僕もPWA LABでいろいろ試した結果、他のページを追加したい理由がないなら start_url: "." で考えるのが一番素直だと感じています。

詳しくは、start_url: “.” が最強説でも整理しています。

scopeも同じくらい重要

start_url と一緒に見直したいのが scope です。

scope は、そのPWAがどこまでをアプリの範囲として扱うかを決める項目です。

たとえば次のようにすると、サイト全体をアプリ範囲にします。

{
  "scope": "/"
}

これは1S1Aなら分かりやすいです。

サイト全体を1つのアプリとして扱いたいからです。

でも、ページごとに別アプリのように扱いたい場合、広すぎる scope は邪魔になることがあります。

特にAndroidでは、scope が広いと同じサイト内の複数ページが同じアプリとして扱われやすくなります。

つまり、AページもBページもCページも、同じアプリの中に吸収される感じです。

1P1Aで「ページごとに別の入口」を作りたいなら、scope を広げすぎないことが大事です。

逆にiPhoneでは、scope を使うことでSafariのミニUI表示に影響することがあります。

このあたりはiOSとAndroidで目的がズレるので、必要ならOSごとにmanifestを出し分ける判断も出てきます。

iPhoneとAndroidのPWAの違いは、iOSとAndroidではPWAのゴールが違うでも書いています。

アイコン設定で表に出ることもある

今回ややこしかったのは、start_url の問題が、アイコン設定を触ったタイミングで目立ったことです。

特に purpose: "maskable" を試したあたりから、PWAとしての扱いが強くなったように見えました。

ただし、URLが変わる直接の原因は maskable ではありません。

原因はあくまで、固定の start_url です。

ただ、purpose: "maskable" 単体は、僕の検証では少し扱いづらい印象でした。

Androidのmaskableアイコンも考えるなら、次のように any maskable にしておく方が安定しやすいです。

{
  "src": "/icon.png",
  "sizes": "512x512",
  "type": "image/png",
  "purpose": "any maskable"
}

通常アイコンとしても、maskableアイコンとしても扱えるようにしておく、という考え方です。

アイコンまわりの詳しい失敗談は、PWAのmaskableアイコンで数時間溶かした話にもまとめています。

apple-touch-iconにも注意する

iPhoneでは、manifestの icons よりも apple-touch-icon が強く効くことがあります。

<link rel='apple-touch-icon' href='/icon.png'>

1つのサイトを1つのPWAとして運用するなら、これは便利です。

iPhoneのホーム画面アイコンを安定させるために使えます。

でも、ページごと・ユーザーごとにアイコンを変えたい場合は注意が必要です。

固定の apple-touch-icon があると、manifest側で別アイコンを指定していても、iPhoneでは固定アイコンが使われることがあります。

つまり、1P1Aのようにページごとのアイコンを作りたい場合、apple-touch-icon が逆に邪魔になることがあります。

URLだけでなく、アイコンまで「思っていたものと違う」状態になるので、動的PWAでは必ず確認した方がいいです。

2026年9月改修での考え方

今回の改修では、考え方をかなりシンプルにしました。

ページを残したい場所では、1P1Aとして設計する。

サイト全体を残したい場所では、1S1Aとして設計する。

この2つを混ぜない。

これが一番大事です。

1P1A側では、基本的に start_url: "." を使います。

必要がなければ、scope も広げすぎません。

ページごとに違うアイコンや名前を使う場合は、固定の apple-touch-icon が邪魔になっていないかも確認します。

一方で、サイト全体を1つのアプリとして使わせたい場合は、start_url: "/" や scope: "/" のような設計でも問題ありません。

大事なのは、どちらが正解かではありません。

何をホーム画面に残したいのかで、manifestの設計を変えることです。

1P1A向けのmanifest例

ページごとにホーム画面へ追加したい場合は、次のような形が分かりやすいです。

{
  "name": "Page App",
  "short_name": "Page App",
  "display": "standalone",
  "start_url": ".",
  "background_color": "#ffffff",
  "theme_color": "#ffffff",
  "icons": [
    {
      "src": "/icon.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ]
}

この形なら、少なくとも固定の start_url によって別ページへ戻される事故は避けやすくなります。

もちろん、実際にはページごとに name や icon を変えるなら、動的にmanifestを生成する必要があります。

でも考え方としては、かなりシンプルです。

今見ているページを残したいなら、起動URLも今のページを基準にする。

1S1A向けのmanifest例

逆に、サイト全体を1つのアプリとして扱うなら、次のような形が自然です。

{
  "name": "Site App",
  "short_name": "Site App",
  "display": "standalone",
  "start_url": "/",
  "scope": "/",
  "background_color": "#ffffff",
  "theme_color": "#ffffff",
  "icons": [
    {
      "src": "/icon.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ]
}

これは、トップへ戻ることが自然なサービス向きです。

たとえば、サービス全体、管理画面、会員サイト、サイト型のPWAならこの設計が合います。

ただし、この設計をページごとのホーム画面追加に使うと、今回のように「追加したURLと起動URLが違う」という問題につながります。

まとめ:URLが勝手に変わる時は、PWAの設計単位を見る

iPhoneでホーム画面に追加したURLが勝手に変わる時は、まずmanifest.jsonの start_url を確認してください。

ただし、それだけで終わらせず、PWAの設計単位も見る必要があります。

  • サイト全体を1つのアプリにしたいのか
  • ページごとに別の入口として残したいのか
  • start_url が固定URLになっていないか
  • scope が広すぎないか
  • apple-touch-icon が固定されていないか
  • purpose: "maskable" 単体で不安定になっていないか

今回の結論はかなりシンプルです。

1P1Aで作るなら、1S1Aのmanifestを書かない。

これです。

ページごとにホーム画面へ追加したいのに、start_url: "/" や scope: "/" のようなサイト全体向け設定を入れると、意図しないURLへ戻される原因になります。

PWAのmanifestは、ただの設定ファイルではありません。

どこを1つのアプリとして扱うのかを決める設計図です。

iOSでURLが勝手に変わるように見えた時は、Safariを疑う前に、まず start_url と scope、そして1S1Aと1P1Aの設計が混ざっていないかを見直すのが早いです。

GoogleでOJapp Tipsを優先する情報源に追加

今後、Google検索でOJapp Tipsの記事を見つけやすくできます。


OJapp FREE · 1P1A

Turn Any Web Page into a Home Screen App

Skip complex PWA setup. Add one line of code and turn your
web page into an installable home screen app.


OJapp FREE - One Page. One App.


OJapp FREE · 1P1A

Webページをホーム画面アプリに

複雑なPWA設定やmanifest.jsonの作成は不要。
1行のコードを追加するだけで、Webページをホーム画面へ追加できるアプリに変えられます。


OJapp FREEでWebページをホーム画面アプリに

OJapp Tips  -  PWA・ホーム画面追加の実機検証ブログ

OJapp Tips  -  PWA・ホーム画面追加の実機検証ブログ

OJapp Tipsは、 公式ドキュメントをなぞるだけでは分かりにくい挙動を、実際にiPhone・Android・PCで検証しながら記録しています。

特に、manifest.json、Service Worker、Web App Manifest、WebClip、アイコンキャッシュ、ホーム画面追加の挙動など、 Webサイトを「アプリのような入口」として使うためのノウハウを中心に扱っています。

OJapp Tipsの記事は、PWA LABでの実機検証や、OJapp・Petal・OJ-Passなど自作ツールの開発で詰まったことを元にしています。 きれいな理論だけではなく、「実際にはここでハマる」という現場寄りの知識を残すための場所です。