[Astro #16] WebサイトをPWA化してデスクトップアプリ(NAVI)として実在させる

[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)の罠に見事はまったので、エラーの解決手順も含めて詳しく残しておきます。

前回の記事:

1. 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',
          }
        ]
      },
    }),
  ],
});

アイコン画像の準備

マニフェストで指定した 192x192512x512 のアプリアイコン画像を作成し、プロジェクトの public フォルダ直下に配置します。

マニフェストで指定した `192x192` と `512x512` のアプリアイコン画像を作成し、プロジェクトの `public` フォルダ直下に配置します。

2. 遭遇したエラーと解決までのトラブルシューティング

ここから npm run dev で起動し、Chromeのデベロッパーツール(F12)の [Application] タブで確認していきましたが、次々と壁にぶつかりました。

トラブル1:マニフェストが検出されない

症状:Applicationタブの「マニフェスト」が空っぽ。「マニフェストが検出されませんでした」と表示される。

症状:Applicationタブの「マニフェスト」が空っぽ。「マニフェストが検出されませんでした」と表示される。 症状:Applicationタブの「マニフェスト」が空っぽ。「マニフェストが検出されませんでした」と表示される。

原因と解決策: HTMLの <head> に、マニフェストを読み込むリンクがありませんでした。共通レイアウト(Layout.astro など)の <head> 内に以下を追記します。

<link rel="manifest" href="/manifest.webmanifest" />
原因と解決策:HTMLの head に、マニフェストを読み込むリンクがありませんでした。共通レイアウト(Layout.astro など)の head 内に以下を追記します。

トラブル2:インラインスクリプトのバンドルエラー (500 Error)

症状:Service Worker を登録するために <script src="/registerSW.js"></script> を追記したところ、Astroが Internal Server Error (500) を吐いて画面が真っ白に。

症状:Service Worker を登録するために script src=/registerSW.js を追記したところ、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) と表示され、インストールボタンが出ない。

症状:エラーは消えたが、コンソールに赤い文字で SW failed! 404 (Not Found) と表示され、インストールボタンが出ない。

原因と解決策: 開発環境(dev)では、プラグインが sw.js を物理的に生成しないため、ブラウザが管理人(Service Worker)を見つけられずに怒っていました。

最終的な解決コード: 外部スクリプトに頼らず、直接 Layout.astro にベタ書きし、さらに public フォルダに空の sw.js を手動で作成するという力技で突破しました。

  1. public フォルダに sw.js を作成(中身は空、または console.log('sw run'); など1行だけ)
  2. 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バーの右端(またはブラウザのメニュー内)に「インストール」アイコンが出現します。

クリックすると独立したウィンドウが立ち上がり、タスクバーにも自作したアイコンが並びます。

Service Workerが起動すると、ついにURLバーの右端(またはブラウザのメニュー内)に「インストール」アイコンが出現 クリックすると独立したウィンドウが立ち上がり、タスクバーにも自作したアイコンが並びます。

「アプリというより、ただのブラウザじゃん」の正体

実際にインストールして起動した直後は、ウィンドウの枠の色が目立っていたりして「これってただのブラウザの枠無しモードじゃん」と感じるかもしれません。

しかし、現代のPCアプリ(Slack、VSCode、Discordなど)の多くは、この「Web技術(HTML/CSS/JS)をブラウザエンジンで動かし、ガワだけアプリ風に見せている」仕組み(Electronなど)を採用しています。PWAもその延長線上にあります。

manifestdisplay: 'standalone' が効くことで、「戻る・進む」やURLバーといったブラウザ由来のノイズが消滅し、純粋な「NAVI(OSのUI)」として没入できるようになります。

まとめ

Webサイトをデスクトップアプリ化するための3条件:

  1. マニフェスト(manifest.webmanifest)の読み込み
  2. アイコン(public 下に適切なサイズ)の配置
  3. Service Worker(sw.js)の登録と起動

開発環境ではファイルがメモリ上にしか存在しないなどのPWA特有のトラップが多いですが、これを乗り越えればどんなWebサイトも「自分のPCにインストール可能なソフトウェア」に進化します。

ワイヤード(情報空間)に過ぎなかったサイトが、リアル(ローカルPC)に実在した瞬間でした。


COMM_LOG: astro-16-pwa-copland-os

NO DATA FOUND IN THIS SECTOR.