saki♮ LabをPWA化した話 — AIアイコン生成からホーム画面追加まで(Part 3)

saki♮ Lab』を、スマートフォンのネイティブアプリのように振る舞わせることにした。いわゆる PWA(プログレッシブウェブアプリ)化 というやつだ。

App Storeの傲慢な審査システムを通すことなく、ユーザーのホーム画面を占拠するためのハックを記録しておく。

PWAとは、Webの境界線を消す技術だ

PWAは、Webサイトをネイティブアプリのようにインストールして使える技術だ。

  • ホーム画面に専用アイコンを配置可能
  • オフライン環境でもキャッシュした範囲で動作
  • ブラウザのUIを排除したスタンドアローン起動
  • AppleやGoogleの承認を待たず配布可能

要するに「アプリを作るほどではないが、ブラウザのタブの中に埋もれさせるには惜しい」という、僕のようなクリエイターのための選択肢だ。

blog-pwa-concept.jpg

実装の骨子

Astro + Cloudflare Workers 構成のサイトに、以下の3要素を実装した。

1. Web App Manifest(manifest.webmanifest)

アプリとしての素性を記述するJSONファイルだ。public/ に配置する。 display: "standalone" に設定することで、起動時にブラウザ特有のUIを排除し、没入感のあるアプリ体験を強制する。

2. Service Worker(sw.js)

この城のオフライン対応を担う執事のような存在だ。キャッシュ管理を記述する。以下のコードを追記することで、ネットワーク要求をインターセプトしてキャッシュを返す仕組みを完成させた。

レイアウトの <head> にmanifestのパスを通し、Service Workerを登録する。

アイコン生成とAIの共犯関係

PWAの顔となるアイコンには、自分のアバターを採用した。猫耳パーカーを纏い、ネオンブルーの「AIキューブ」を抱えて眠る僕自身だ。 Leonardo.ai(GPT Image 1.5) に以下のプロンプトを投げ、生成された画像はPython(Pillow)を用いて必要なサイズへ機械的にリサイズした。

現代Webの仕様という名の壁(ハマりどころ)

実装の過程で、いくつか「知らなければ時間をドブに捨てる」仕様に遭遇した。

① スクリーンショットのsizes指定

manifestの screenshots セクションにおいて、sizes を欠くとChrome DevToolsは容赦なくエラーを吐く。

② maskableアイコンの罠

purpose: "maskable" を指定すると、OSがアイコンの外周を自動クロップする。キャラをそのまま詰め込むと耳が削ぎ落とされるため、キャラを80%サイズに縮小し、外周20%を背景色(#0d0b09)で埋めるという、物理的な調整が必要だった。

③ インストールの真実

完全なPWAとして認識されると、Chromeは「ホーム画面に追加」ではなく「インストール」という文言を出す(仕様になった?どちらも出てた記憶あるけど)。

当初は「なぜメニューが変わったのか」と困惑したが、これはPWAが正しく機能している証拠だ。インストール後はアプリドロワーからアイコンを長押しし、手動でホーム画面に配置する。これがこの界隈の流儀らしい。たぶん・・・

完成

ホーム画面にアイコンが並んだ瞬間、このサイトはただのWebサイトから「僕のアプリ」へと昇華した。 技術的にはWebの延長線上に過ぎないが、ホーム画面という一等地に城への扉を置くことで、ユーザーとの距離感は劇的に変わる。

App Storeという巨大なシステムの管理下に置かれることなく、自分の城を直接誰かのデバイスへインストールさせる。これこそが、僕たちが選ぶべき自由だ。

使用技術: Astro / Cloudflare Workers / Service Worker / Leonardo.ai(GPT Image 1.5)/ Python(Pillow)