[.NET 8]素のBlazorWebAppにチョイ足しでPWAを作る

# 忙しい人向けに結論

1. Blazor Web Appテンプレートでアプリケーションを作成する。
1. サーバ側プロジェクトの `App.razor` の `<head>` タグ内で `manifest` を参照する。
1. 同じくサーバ側プロジェクトの `App.razor` の `<body>` タグ内の最後で `service-worker.js` を参照する。
1. サーバ側プロジェクト内の `wwwroot` フォルダ内に以下を配置する。
    - `manifest.webmanifest`
    - `service-worker.js`
    - `manifest.webmanifest` 内で参照している `icon` ファイル
1. デバッグ実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/77c0aad4-8d90-fd47-9689-e727fdab5e49.png)

ね、簡単でしょう？
以下で、解説をしていきます。

# Blazor Web Appって？

Blazor Web Appは.NET 8より追加されたプロジェクトテンプレートで、.NET 7までのBlazor ServerとBlazor WebAssemblyを合体させたようなものです。
具体的には、ページやコンポーネント単位でサーバーサイドレンダリング、ストリーミングレンダリング、WebAssemblyでの動作を自動的に選択し、クライアントの状況に応じたインタラクティブなWebアプリを実現するテンプレートとなっています。
Blazor ServerとBlazor WebAssemblyのメリットの両方を享受できるため、これから新規に開発するのであればBlazor Web Appテンプレートを使用していくのが良い判断と言えるでしょう。

# Blazor Web Appテンプレートでアプリケーションを作成する

Visual Studio 2022を使用して説明していきます。
まずはBlazor Web Appテンプレートを選択して、新しいプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/ab99f867-1de4-be26-9143-b6524957ac30.png)

任意のプロジェクト名を設定します。ここでは `BlazorApp1` で進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/f3c4e87d-9f0f-7968-8430-fb007a591476.png)

追加情報では以下の通り設定します。
|項目|値|
|--|--|
|フレームワーク|.NET 8.0（長期的なサポート）|
|認証の種類|なし|
|HTTPS用の構成|✅|
|Interactive render mode|Auto (Server and WebAssembly)|
|Interactivity location|Per page/component|
|Include sample pages|✅|
|Do not use top-level statements|✅|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/f0ed80c6-d342-4ee5-9939-6935cbf59505.png)

作成ボタンをクリックすると以下のプロジェクトが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/ea53d07f-5436-eab5-d249-0112a90b047b.png)

`BlazorApp1` がサーバ側のプロジェクト、 `BlazorApp1.Client` がクライアント側のプロジェクトになります。

# `App.razor` の編集

続いて、以下のコードを参考にサーバ側の `Components/App.razor` ファイルを編集します。

```diff_html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="BlazorApp1.styles.css" />
    <link rel="icon" type="image/png" href="favicon.png" />
+   <link href="manifest.json" rel="manifest" />
    <HeadOutlet />
</head>

<body>
    <Routes />
    <script src="_framework/blazor.web.js"></script>
+   <script>navigator.serviceWorker.register('service-worker.js');</script>
</body>

</html>
```

# Blazor WebAssemblyアプリから `manifest.webmanifest` と `service-worker.js` をコピーする

自分でmanifestファイルやservice-workerを作成しても良いですが、手間がかかるので、Blazor WebAssemblyアプリからコピーしましょう。
`Blazor WebAssmblyアプリ` テンプレートを使用し、新しいプロジェクトを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/b2568e72-7390-bb01-a4b3-3d65a0349b2a.png)

任意のプロジェクト名を設定します。ここでは、 `BlazorApp2` とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/01e06acf-3fac-368e-8b79-c0c9fdb30aeb.png)

追加情報では以下の通り設定します。
|項目|値|
|--|--|
|フレームワーク|.NET 8.0（長期的なサポート）|
|認証の種類|なし|
|HTTPS用の構成|✅|
|プログレッシブ Web アプリケーション|✅|
|Include sample pages|✅|
|最上位レベルのステートメントを使用しない|✅|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/cfb82287-aaea-2578-8ff1-0749825e65bd.png)

プロジェクトを追加すると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/ace6a646-78c3-aca1-f938-202e37399e44.png)

続いて、 `BlazorApp2` の以下のファイルを `BlazorApp1` の `wwwroot` フォルダにコピーします。

- `wwwroot/icon-192.png`
- `wwwroot/icon-512.png`
- `wwwroot/manifest.webmanifest`
- `wwwroot/service-worker.js`
- `wwwroot/service-worker.published.js`

コピー後のプロジェクト構成は以下のようになると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/2bd76d88-4764-a2b0-94a7-8a54969fded1.png)

最後に、 `BlazorApp1` の `wwwroot/manifest.webmanifest` を一部修正します。

```diff_json
{
- "name": "BlazorApp2",
+ "name": "BlazorApp1",
- "short_name": "BlazorApp2",
+ "short_name": "BlazorApp1",
  "id": "./",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#03173d",
  "prefer_related_applications": false,
  "icons": [
    {
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    },
    {
      "src": "icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
    }
  ]
}

```

# デバッグ実行する

インストールダイアログが登場します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/03355920-16dc-bef5-b4f8-dfa076f2fb46.png)

当たり前ですがインストールすれば、PWAとして動作します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/d2088b69-ff9a-b910-37e4-77cfb221fc4b.png)

# おわり

これを参考にみなさんもよい.NETライフを！

# 最後の最後にちょっとだけ宣伝を

この記事を書いた @nr_ck が主宰するサークルきじのしっぽは、2023年12月31日のコミックマーケット103に参加します！
新刊は **「.NETだってM5Stackしたい！」** （A5/36ページ）です！
[<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/9cc25ce1-d963-8b79-b639-86a3b2292aec.png" width="50%"/>](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160980/9cc25ce1-d963-8b79-b639-86a3b2292aec.png)


ご興味ある方はぜひお越しください～！
**東京ビッグサイト 東2ホールU56aで待ってるよ！**
- **コミケWebカタログ - きじのしっぽ**
    - https://webcatalog.circle.ms/Circle/18011518