# 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) · 🇯🇵 [ja](../../../ja/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) --- OmniRoute 以可完整安裝的漸進式網頁應用程式形式提供。當您從任何行動瀏覽器存取儀表板時——Android(Chrome)或 iOS(Safari)——您可以「加入主畫面」,無須透過應用程式商店即可獲得如原生應用程式般的體驗。 ## 什麼是 PWA? 漸進式網頁應用程式可將 OmniRoute 網頁儀表板轉換成外觀與操作體驗皆如同原生行動應用程式的形式。安裝後,它可以: - 從主畫面透過專屬圖示啟動 - 以全螢幕開啟——沒有瀏覽器網址列或分頁介面 - 可離線運作,並提供專用的連線狀態頁面 - 快取靜態資產以加快載入速度 - 同時支援直向與橫向顯示 ## 安裝 ### Android(Chrome) 1. 在 Chrome 中開啟 OmniRoute 儀表板:`http://YOUR_IP:20128` 2. Chrome 會自動顯示 **「將 OmniRoute 加入主畫面」** 橫幅,或者: - 點選 **⋮** 選單(三個點)→ **「加入主畫面」** 或 **「安裝應用程式」** 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"`,這表示安裝後的應用程式會使用整個螢幕——沒有瀏覽器介面,也不會與狀態列重疊。這可讓儀表板帶來真正如同原生應用程式般的體驗。 ### 離線支援 OmniRoute 包含一個提供智慧型快取功能的 Service Worker(`sw.js`): | 資產類型 | 策略 | 行為 | | ---------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------------ | | **應用程式殼層** | 快取優先 | 在安裝時預先快取 `/`、`/offline`、資訊清單與圖示 | | **靜態資產**(CSS、JS、圖片、字型) | 網路優先,快取作為備援 | 從網路擷取最新內容;離線時改用快取 | | **Next.js 套件組合**(`/_next/`) | 網路優先並更新快取 | 從網路擷取內容並更新快取;離線時提供快取版本 | | **導覽請求** | 略過(絕不攔截) | 由瀏覽器處理 HTTP/3→HTTP/2 備援;失效的 QUIC 通訊端不得變成 `Response.error()` | | **API/儀表板路由**(`/api/`、`/a2a`、`/dashboard`) | 略過(絕不快取) | 一律直接連線至伺服器——絕不由 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(不依賴任何框架),具備: - **安裝階段**:預先快取應用程式外殼(根目錄、離線頁面、manifest、圖示) - **啟用階段**:清除舊版快取並接管所有用戶端 - **擷取階段**:根據請求類型(導覽、靜態資源、API)進行智慧路由 - **快取版本控制**:`omniroute-pwa-v3` — 更新時提高此版本號,以強制建立全新快取 ### 版面配置中繼資料(`src/app/layout.tsx`) 根版面配置提供符合 PWA 規範所需的所有 meta 標籤: - 指向 `/manifest.webmanifest` 的 `manifest` 連結 - `apple-web-app-capable: true`,用於 iOS 獨立模式 - `apple-web-app-status-bar-style: black-translucent` - `mobile-web-app-capable: yes`,用於 Android Chrome - `theme-color: #0b0f1a` - `viewport-fit: cover`,用於邊到邊顯示 ### 元件:`PwaRegister` 位於 `src/shared/components/PwaRegister.tsx`,此用戶端元件會: 1. 在掛載時執行(僅限用戶端) 2. 檢查瀏覽器是否支援 `serviceWorker` 3. 靜默註冊 `/sw.js`(錯誤會被忽略,以避免阻礙應用程式執行) 4. 不渲染任何內容(`return null`)— 此元件僅用於執行副作用 ## 搭配 Termux 使用(Android) 透過 Termux 在 Android 上執行 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 - **筆記型電腦**:開啟 Chrome/Edge,並將其安裝為桌面 PWA - **具備瀏覽器的智慧型電視**:以全螢幕模式存取儀表板 ## 自訂 ### 執行個體名稱 PWA 標題會採用 `Dashboard → Settings` 中的 **Instance Name** 設定。如果您將執行個體重新命名為「My AI Gateway」,已安裝的 PWA 將顯示該名稱。 ### 自訂 Favicon 如果您透過 `Dashboard → Settings` 上傳自訂 favicon,桌面版 PWA 圖示將會反映該自訂圖示。行動裝置主畫面圖示則使用預先建立的 `icon-512.png` 與 `apple-touch-icon.png` 檔案。 ## 限制 - **不支援推播通知** — Service worker 未實作 Push API。通知改由 Electron 應用程式處理。 - **不支援背景同步** — 離線操作不會排入佇列以供稍後重新執行。PWA 主要用作儀表板檢視器。 - **iOS 限制** — iOS 上的 Safari 不支援所有 PWA 功能(例如,安裝提示需要手動操作,且背景 service worker 的功能受限)。 - **快取大小** — Service worker 僅快取靜態資源。來自 `/api/` 路由的大型回應承載內容絕不會被快取。 - **行動裝置上的自訂圖示** — 在設定中變更 favicon 不會更新行動裝置上的主畫面圖示(這需要重新產生 PWA 圖示)。 ## 檔案參考 | 檔案 | 用途 | | --------------------------------------- | -------------------------------------------------------------- | | `src/app/manifest.ts` | Next.js manifest 路由(產生 `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 備援) |