[Astro #16] WebサイトをPWA化してデスクトップアプリ(NAVI)として実在させる
はじめに
前回の記事([Astro #15] SVG lain clock update & bug fix)で時計UIが完成しました。
しかし、ブラウザのタブの中に閉じ込められている状態では、まだ単なる「Webサイト」に過ぎません。
今回は、この時計をPWA(Progressive Web App)化し、PCのデスクトップに常駐する独立したアプリ(Copland OS NAVI)として「実在」させるまでの全記録をまとめました。
すんなり行くと思いきや、Astro特有のビルド仕様や開発環境(dev)の罠に見事はまったので、エラーの解決手順も含めて詳しく残しておきます。
前回の記事:
[Astro #15] Copland OS: SVG clock 無段階サイズ変更と、SPA特有のバグを攻略 // PROTOCOL.LAIN
AstroとNext.jsの混在環境で発生するSPA特有のイベントリスナー重複や、requestAnimationFrameの停止処理など、実戦的なデバッグ手法をまとめました。
humanxai.info1. PWA化プラグインの導入と基本設定
まずは Astro プロジェクトを PWA に対応させるための公式インテグレーション @vite-pwa/astro を導入します。
npx astro add @vite-pwa/astro
次に、astro.config.mjs にマニフェスト(アプリの設計図)の設定を記述します。
// astro.config.mjs
import { defineConfig } from 'astro/config';
import AstroPWA from '@vite-pwa/astro';
export default defineConfig({
integrations: [
AstroPWA({
devOptions: {
enabled: true, // 開発環境(npm run dev)でもPWAを有効にする
},
manifest: {
id: '/',
name: 'Copland OS NAVI',
short_name: 'Copland',
description: 'Wired integration clock for your desktop.',
theme_color: '#00ff00', // タイトルバーの色など
background_color: '#000000',
display: 'standalone', // ブラウザのUIを消してアプリ化する設定
icons: [
{
src: 'icon-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'icon-512x512.png',
sizes: '512x512',
type: 'image/png'
}
],
screenshots: [
{
src: 'screenshot.png', // インストール時に表示される画像
sizes: '1280x720',
type: 'image/png',
form_factor: 'wide',
}
]
},
}),
],
});
アイコン画像の準備
マニフェストで指定した 192x192 と 512x512 のアプリアイコン画像を作成し、プロジェクトの public フォルダ直下に配置します。
2. 遭遇したエラーと解決までのトラブルシューティング
ここから npm run dev で起動し、Chromeのデベロッパーツール(F12)の [Application] タブで確認していきましたが、次々と壁にぶつかりました。
トラブル1:マニフェストが検出されない
症状:Applicationタブの「マニフェスト」が空っぽ。「マニフェストが検出されませんでした」と表示される。
原因と解決策:
HTMLの <head> に、マニフェストを読み込むリンクがありませんでした。共通レイアウト(Layout.astro など)の <head> 内に以下を追記します。
<link rel="manifest" href="/manifest.webmanifest" />
トラブル2:インラインスクリプトのバンドルエラー (500 Error)
症状:Service Worker を登録するために <script src="/registerSW.js"></script> を追記したところ、Astroが Internal Server Error (500) を吐いて画面が真っ白に。
<script src="/registerSW.js"> references an asset in the "public/" directory.
Please add the "is:inline" directive to keep this asset from being bundled.
原因と解決策:
Astroが気を利かせてスクリプトを最適化(バンドル)しようとした結果、存在しない仮想ファイルにアクセスして自爆していました。エラー文の指示通り、is:inline を付けてAstroの処理をバイパスさせます。
トラブル3:Service Worker が 404 (Not Found)
症状:エラーは消えたが、コンソールに赤い文字で SW failed! 404 (Not Found) と表示され、インストールボタンが出ない。
原因と解決策:
開発環境(dev)では、プラグインが sw.js を物理的に生成しないため、ブラウザが管理人(Service Worker)を見つけられずに怒っていました。
最終的な解決コード:
外部スクリプトに頼らず、直接 Layout.astro にベタ書きし、さらに public フォルダに空の sw.js を手動で作成するという力技で突破しました。
publicフォルダにsw.jsを作成(中身は空、またはconsole.log('sw run');など1行だけ)Layout.astroの<head>に以下を記述:
<script is:inline>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js', { scope: '/' })
.then(reg => console.log('SW registered!', reg))
.catch(err => console.error('SW failed!', err));
});
}
</script>
これで再度リロードすると、ついにコンソールに SW registered! が表示され、Applicationタブの [Service workers] に緑色の「実行中」マークが点灯しました!
3. インストールと「アプリ」としての実在
Service Workerが起動すると、ついにURLバーの右端(またはブラウザのメニュー内)に「インストール」アイコンが出現します。
クリックすると独立したウィンドウが立ち上がり、タスクバーにも自作したアイコンが並びます。
「アプリというより、ただのブラウザじゃん」の正体
実際にインストールして起動した直後は、ウィンドウの枠の色が目立っていたりして「これってただのブラウザの枠無しモードじゃん」と感じるかもしれません。
しかし、現代のPCアプリ(Slack、VSCode、Discordなど)の多くは、この「Web技術(HTML/CSS/JS)をブラウザエンジンで動かし、ガワだけアプリ風に見せている」仕組み(Electronなど)を採用しています。PWAもその延長線上にあります。
manifest の display: 'standalone' が効くことで、「戻る・進む」やURLバーといったブラウザ由来のノイズが消滅し、純粋な「NAVI(OSのUI)」として没入できるようになります。
まとめ
Webサイトをデスクトップアプリ化するための3条件:
- マニフェスト(
manifest.webmanifest)の読み込み - アイコン(
public下に適切なサイズ)の配置 - Service Worker(
sw.js)の登録と起動
開発環境ではファイルがメモリ上にしか存在しないなどのPWA特有のトラップが多いですが、これを乗り越えればどんなWebサイトも「自分のPCにインストール可能なソフトウェア」に進化します。
ワイヤード(情報空間)に過ぎなかったサイトが、リアル(ローカルPC)に実在した瞬間でした。
COMM_LOG: astro-16-pwa-copland-os