# Progressive Web App (PWA) Guide (日本語) 🌐 **Languages:** 🇺🇸 [English](../../../../guides/PWA_GUIDE.md) · 🇪🇹 [am](../../../am/docs/guides/PWA_GUIDE.md) · 🇸🇦 [ar](../../../ar/docs/guides/PWA_GUIDE.md) · 🇦🇿 [az](../../../az/docs/guides/PWA_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/guides/PWA_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/guides/PWA_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/guides/PWA_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/guides/PWA_GUIDE.md) · 🇩🇰 [da](../../../da/docs/guides/PWA_GUIDE.md) · 🇩🇪 [de](../../../de/docs/guides/PWA_GUIDE.md) · 🇬🇷 [el](../../../el/docs/guides/PWA_GUIDE.md) · 🇪🇸 [es](../../../es/docs/guides/PWA_GUIDE.md) · 🇪🇪 [et](../../../et/docs/guides/PWA_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/guides/PWA_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/guides/PWA_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/guides/PWA_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/guides/PWA_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/guides/PWA_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/guides/PWA_GUIDE.md) · 🇮🇱 [he](../../../he/docs/guides/PWA_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/guides/PWA_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/guides/PWA_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/guides/PWA_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/guides/PWA_GUIDE.md) · 🇮🇩 [id](../../../id/docs/guides/PWA_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/guides/PWA_GUIDE.md) · 🇮🇹 [it](../../../it/docs/guides/PWA_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/guides/PWA_GUIDE.md) · 🇰🇭 [km](../../../km/docs/guides/PWA_GUIDE.md) · 🇮🇳 [kn](../../../kn/docs/guides/PWA_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/guides/PWA_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/guides/PWA_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/guides/PWA_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/guides/PWA_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/guides/PWA_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/guides/PWA_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/guides/PWA_GUIDE.md) · 🇲🇲 [my](../../../my/docs/guides/PWA_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/guides/PWA_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/guides/PWA_GUIDE.md) · 🇳🇴 [no](../../../no/docs/guides/PWA_GUIDE.md) · 🇮🇳 [or](../../../or/docs/guides/PWA_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/guides/PWA_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/guides/PWA_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/guides/PWA_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/guides/PWA_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/guides/PWA_GUIDE.md) · 🇷🇴 [ro](../../../ro/docs/guides/PWA_GUIDE.md) · 🇷🇺 [ru](../../../ru/docs/guides/PWA_GUIDE.md) · 🇱🇰 [si](../../../si/docs/guides/PWA_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/guides/PWA_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/guides/PWA_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/guides/PWA_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/guides/PWA_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/guides/PWA_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/guides/PWA_GUIDE.md) · 🇮🇳 [te](../../../te/docs/guides/PWA_GUIDE.md) · 🇹🇭 [th](../../../th/docs/guides/PWA_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/guides/PWA_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/guides/PWA_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/guides/PWA_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/guides/PWA_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/guides/PWA_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/guides/PWA_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/guides/PWA_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/guides/PWA_GUIDE.md) --- OmniRoute は、完全にインストール可能な Progressive Web App として提供されます。Android(Chrome)または iOS(Safari)など、どのモバイルブラウザからダッシュボードにアクセスしても、「ホーム画面に追加」することで、アプリストアを必要とせず、ネイティブアプリのような操作体験を得られます。 ## PWA とは? Progressive Web App は、OmniRoute の Web ダッシュボードを、ネイティブモバイルアプリのような外観と操作感を持つアプリに変換します。インストールすると、次のことが可能になります。 - 独自のアイコンからホーム画面上で起動 - フルスクリーンで表示 — ブラウザのアドレスバーやタブ UI は非表示 - 専用の接続状態ページによりオフラインでも動作 - 静的アセットをキャッシュして読み込みを高速化 - 縦向きと横向きの両方に対応 ## インストール ### Android(Chrome) 1. Chrome で OmniRoute ダッシュボードを開きます:`http://YOUR_IP:20128` 2. Chrome に **「OmniRoute をホーム画面に追加」** バナーが自動的に表示されます。または、次の手順を実行します。 - **⋮** メニュー(3 点リーダー)をタップ → **「ホーム画面に追加」** または **「アプリをインストール」** 3. プロンプトを確認します 4. OmniRoute がスタンドアロンアプリとしてホーム画面に表示されます ### iOS(Safari) 1. Safari で OmniRoute ダッシュボードを開きます:`http://YOUR_IP:20128` 2. **共有** ボタン(矢印付きのボックス)をタップします 3. 下にスクロールし、**「ホーム画面に追加」** をタップします 4. 名前を指定し(デフォルトは「OmniRoute」)、**追加** をタップします 5. OmniRoute がアプリアイコンとともにホーム画面に表示されます ### デスクトップ(Chrome / Edge) 1. OmniRoute ダッシュボードを開きます 2. アドレスバーの **インストールアイコン** をクリックします(または ⋮ →「OmniRoute をインストール...」) 3. プロンプトを確認します 4. OmniRoute がスタンドアロンウィンドウで開きます — タブもアドレスバーも表示されません ## 機能 ### フルスクリーン表示 マニフェストは `display: "fullscreen"` に設定されているため、インストールされたアプリは画面全体を使用します。ブラウザ UI は表示されず、ステータスバーとの重なりもありません。これにより、ダッシュボードを真のネイティブアプリのように使用できます。 ### オフライン対応 OmniRoute には、インテリジェントなキャッシュ機能を提供する Service Worker(`sw.js`)が含まれています。 | アセットの種類 | 戦略 | 動作 | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **アプリシェル** | キャッシュ優先 | インストール時に `/`、`/offline`、マニフェスト、アイコンを事前キャッシュ | | **静的アセット**(CSS、JS、画像、フォント) | ネットワーク優先、キャッシュにフォールバック | ネットワークから最新版を取得し、オフラインの場合はキャッシュを使用 | | **Next.js バンドル**(`/_next/`) | ネットワーク優先、キャッシュを更新 | ネットワークから取得してキャッシュを更新し、オフラインの場合はキャッシュ版を提供 | | **ナビゲーションリクエスト** | バイパス(インターセプトしない) | HTTP/3→HTTP/2 のフォールバックはブラウザが処理します。停止した QUIC ソケットが `Response.error()` にならないようにします | | **API / ダッシュボードルート**(`/api/`、`/a2a`、`/dashboard`、クライアント API のエイリアス `/v1`、`/v1beta`、`/models`、`/chat`、`/responses`、`/codex`、および `/callback`、`/login`。大文字と小文字を区別せずに照合) | バイパス(キャッシュしない) | 常にサーバーへ直接送信され、Service Worker によってインターセプトされません | ### オフラインページ ネットワークを利用できない状態でユーザーが新しいページへ移動すると、Service Worker は専用の `/offline` ページを提供します。このページでは、次の機能を利用できます。 - 明確な **「接続の問題」** メッセージを表示 - リアルタイムで更新される **オンライン/オフライン状態インジケーター** を表示 - 接続が復旧したときに再読み込みするための **「接続を再試行」** ボタンを提供 - 診断用の **ステータスページ** へのリンクを提供 ### アプリアイコン OmniRoute は、各プラットフォーム向けに最適化されたアイコンを提供します。 | ファイル | サイズ | 使用箇所 | | ---------------------- | ------------------- | -------------------------------------------------- | | `icon-512.png` | 512×512 | Android のインストールプロンプト、スプラッシュ画面 | | `apple-touch-icon.png` | 180×180 | iOS のホーム画面アイコン | | `icon-192.svg` | 192×192(ベクター) | Android のアダプティブアイコン | | `apple-touch-icon.svg` | 180×180(ベクター) | Apple 向けフォールバック | | `favicon.svg` | ベクター | ブラウザタブ | | `favicon.ico` | 複数サイズ | レガシーブラウザ | ### 自動登録 Service Worker は、ルートレイアウトの `` コンポーネントを介して自動的に登録されます。ユーザーによる操作は不要です。ブラウザが有効なマニフェストと Service Worker を検出すると、すぐにアプリをインストールできるようになります。 ## 技術アーキテクチャ ### Web App Manifest (`manifest.webmanifest`) Next.js により `src/app/manifest.ts` から生成されます。 ```json { "name": "OmniRoute", "short_name": "OmniRoute", "description": "OmniRoute は、複数プロバイダーの LLM に対応する AI ゲートウェイです。すべての AI プロバイダーを単一のエンドポイントで利用できます。", "start_url": "/", "scope": "/", "display": "fullscreen", "orientation": "any", "background_color": "#0b0f1a", "theme_color": "#0b0f1a", "icons": [ { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }, { "src": "/apple-touch-icon.png", "sizes": "180x180", "type": "image/png" } ] } ``` ### Service Worker (`public/sw.js`) フレームワークに依存しない、素の Service Worker であり、次の機能を備えています。 - **インストールフェーズ**: アプリシェル(ルート、オフラインページ、マニフェスト、アイコン)を事前にキャッシュします - **アクティベートフェーズ**: 古いバージョンのキャッシュを削除し、すべてのクライアントを制御下に置きます - **フェッチフェーズ**: リクエストの種類(ナビゲーション、静的アセット、API)に基づいてインテリジェントにルーティングします - **キャッシュのバージョン管理**: `omniroute-pwa-v3` — 更新時に新しいキャッシュを強制的に作成するには、この値を増やします ### レイアウトメタデータ (`src/app/layout.tsx`) ルートレイアウトは、PWA 準拠に必要なすべてのメタタグを提供します。 - `/manifest.webmanifest` への `manifest` リンク - iOS のスタンドアロンモード用の `apple-web-app-capable: true` - `apple-web-app-status-bar-style: black-translucent` - Android Chrome 用の `mobile-web-app-capable: yes` - `theme-color: #0b0f1a` - エッジツーエッジレンダリング用の `viewport-fit: cover` ### コンポーネント: `PwaRegister` `src/shared/components/PwaRegister.tsx` に配置されているこのクライアントコンポーネントは、次のように動作します。 1. マウント時に実行されます(クライアントサイドのみ) 2. ブラウザーが `serviceWorker` をサポートしているか確認します 3. `/sw.js` を通知なしで登録します(アプリの動作を妨げないよう、エラーは無視されます) 4. 何もレンダリングしません(`return null`)— 副作用のみを目的としたコンポーネントです ## Termux(Android)での使用 Android 上の Termux で OmniRoute を実行する場合も、PWA はシームレスに動作します。 1. Termux で OmniRoute を起動します: `npx omniroute` 2. 同じスマートフォンで Chrome を開きます: `http://localhost:20128` 3. 「ホーム画面に追加」から PWA をインストールします 4. PWA がローカルの Termux サーバーに接続し、すべてがデバイス上で動作します この組み合わせにより、Android スマートフォンが **サーバー**(Termux)と **クライアント**(PWA)の両方として機能し、完全に自己完結型の AI ゲートウェイとなります。 ## 他のデバイスからの使用 OmniRoute サーバーにブラウザーからアクセスできる任意のデバイスに PWA をインストールできます。 - **別のスマートフォン/タブレット**: `http://PHONE_IP:20128` にアクセスして PWA をインストールします - **ノート PC**: Chrome/Edge で開き、デスクトップ PWA としてインストールします - **ブラウザー搭載スマートテレビ**: ダッシュボードにフルスクリーンでアクセスします ## カスタマイズ ### インスタンス名 PWA のタイトルには、`Dashboard → Settings` の **Instance Name** 設定が反映されます。インスタンス名を「My AI Gateway」に変更すると、インストールされた PWA にその名前が表示されます。 ### カスタムファビコン `Dashboard → Settings` からカスタムファビコンをアップロードすると、デスクトップ上の PWA アイコンにそのカスタムアイコンが反映されます。モバイルのホーム画面アイコンには、事前に用意された `icon-512.png` ファイルと `apple-touch-icon.png` ファイルが使用されます。 ## 制限事項 - **プッシュ通知なし** — Service Worker は Push API を実装していません。代わりに、通知は Electron アプリによって処理されます。 - **バックグラウンド同期なし** — オフライン時の操作は、再実行のためにキューへ追加されません。PWA は主にダッシュボードの閲覧を目的としています。 - **iOS の制限** — iOS の Safari は、すべての PWA 機能をサポートしているわけではありません(例:インストールは手動で行う必要があり、バックグラウンドでの Service Worker の動作には制限があります)。 - **キャッシュサイズ** — Service Worker は静的アセットのみをキャッシュします。`/api/` ルートからのサイズの大きなレスポンスペイロードは、キャッシュされません。 - **モバイルでのカスタムアイコン** — 設定でファビコンを変更しても、モバイルのホーム画面アイコンは更新されません(更新するには PWA アイコンを再生成する必要があります)。 ## ファイルリファレンス | ファイル | 用途 | | --------------------------------------- | ----------------------------------------------------------------------- | | `src/app/manifest.ts` | Next.js のマニフェストルート(`manifest.webmanifest` を生成) | | `public/sw.js` | キャッシュロジックを備えた Service Worker | | `src/shared/components/PwaRegister.tsx` | Service Worker を登録するクライアントコンポーネント | | `src/app/offline/page.tsx` | リアルタイムのステータスインジケーターを備えたオフライン時の代替ページ | | `src/app/layout.tsx` | PWA メタデータ(apple-web-app、theme-color など)を含むルートレイアウト | | `public/icon-512.png` | 512×512 PNG アイコン(Android、スプラッシュ画面) | | `public/apple-touch-icon.png` | 180×180 PNG アイコン(iOS ホーム画面) | | `public/icon-192.svg` | 192×192 SVG アイコン(Android アダプティブ) | | `public/apple-touch-icon.svg` | 180×180 SVG アイコン(Apple 向けフォールバック) |