（随時更新）.NET 6.0 + Blazor WASM + Tailwind CSSでアプリ開発する基礎工程を構築する。

# まえおき
- この内容はメモです。間違っている場合があります・・・。
- うまくいかない場合や間違っている指摘、アドバイスはコメントでお願いします。
- デザイン知識ゴミな開発者なので、コピペで実装できる方法を探してTailwind CSSを試行しています。

# 筆者環境
- VisualStudio2022 CommunityEdition v17.2.0 preview5 (17.0.4はバグでHotReloadが動かない) 
- .NET 6.0
- Blazor WASM
- Node.js v16.13.2
- Tailwind CSS v3.0.23

# これを読んでできること
- BlazorWASMのプロジェクトを作成し、TailwindCSS仕様に変更する。
- ログイン機能の実装(作成中)
- 成果物
https://github.com/enngawa/BlazorTailwind/tree/%E7%AC%AC1%E5%9B%9E/BlazorTailwind

# プロジェクト作成

<details>
<summary>Blazor WASMプロジェクトの作成</summary>
<div>
「Blazor WebAssenmblyアプリ」を選択して、「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/163ba203-ae06-dc9a-888d-9ac01605d1e8.png)

プロジェクト名を適当に設定して、「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/9765f31d-69f2-882e-e33e-857f040e0ff6.png)

設定を以下のように変更して、「作成」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/8db1e5fc-b049-cee1-0283-bf3f251b916e.png)

> 認証をONにすると、認証の画面がサーバーサイドで実装されて管理が面倒になる。今回は認証はOFFにして、クライアントサイドで手動実装する予定。
</div>
</details>

#Tailwind CSSの導入
> 参考： codewithmukesh - Integrating Tailwind CSS with Blazor – Detailed Guide
> https://codewithmukesh.com/blog/integrating-tailwind-css-with-blazor/


<details>
<summary>TailwindCSSのインストール</summary>
<div>

ソリューションエクスプローラーから、Clientプロジェクトを右クリックして、「ターミナルで開く」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/1a4c0ae9-e85a-e127-205e-4eea813a8afa.png)

開いた開発用PowerShell(以下、ターミナル)で、「`npm version`」を実行しnpmが実行できることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/d23c7184-cea7-576d-768b-ac13d24a12a1.png)
> 正常にインストールされている場合は、nodeの各コンポーネントのバージョンが表示される。
> nodeがインストールされていない場合、古い場合は、LTSバージョンのnodeをインストールする。
> https://nodejs.org/ja/download/

ターミナルで「`npm init`」コマンドを実行。実行すると設定値を聞かれるので、設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/be0f9eea-4536-038a-7201-da2a49121766.png)
> よくわからなければ、何も入力せずにエンター(初期値が設定される)を押して進める。
> npmパッケージ用の設定ファイル「package.json」が Clientフォルダに作成される。

「`npm install tailwindcss postcss autoprefixer postcss-cli`」コマンドを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/d6303dee-784b-77ae-03cb-1a0fc4b7e067.png)
> npmにより、tailwindcss、postcss、autoprefixer、postcss-cliがインストールされる。

「[ClientProject]/postcss.config.js」を追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/75510b27-c3dc-0839-1193-db8707dbc98c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/d3b0b8fb-bf18-da20-d2af-6c0a6b005d37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/59b2aeac-72c1-938f-d516-94c29f8eb9cd.png)

追加した「postcss.config.js」ファイルに以下のコードを貼り付け、保存する。

```js:postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}
```

ターミナルで「`npx tailwindcss init`」コマンドを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/16b5c118-bacd-e0d1-0c93-637308d1d7c8.png)
> tailwind.config.jsが自動で作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/863b1933-44d0-8282-8179-e27880125523.png)

作成された「tailwind.config.js」を以下のように書き換える

```js:tailwind.config.js
module.exports = {
    content: [
        './**/*.html',
        './**/*.razor'
    ],
    variants: {
        extend: {},
    },
    plugins: [],
}
```

Clientプロジェクトの「[ClientProject]/wwwroot/css」フォルダ配下をすべて削除する。(bootstrapを排除する)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/c7ec3019-5118-03bc-0bc9-39151c62fc00.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/a1cdd316-099a-1750-033e-0e9bc28eb088.png)

「[ClientProject]/wwwroot/css/app.css」を作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/250d503f-920c-2b00-5cea-b5505033cafb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/3e20c6c1-6cff-2ad1-c6c8-52885af9dbc8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/52cb2d70-0a48-c264-ec96-268d829d76de.png)

「[ClientProject]/wwwroot/css/app.css」に以下のコードに書き換える。

```css:[ClientProject]/wwwroot/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

```
「[ClientProject]/package.json」を開き、「`"buildcss" ："postcss wwwroot/css/app.css -o wwwroot/css/app.min.css"`」をscriptsへ追加する。

```json:[ClientProject]/package.json
{
  "name": "client",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "buildcss": "postcss wwwroot/css/app.css -o wwwroot/css/app.min.css"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "autoprefixer": "^10.4.2",
    "postcss": "^8.4.7",
    "postcss-cli": "^9.1.0",
    "tailwindcss": "^3.0.23"
  }
}

```

ターミナルで「npm run buildcss」を実行する。（cssファイルを生成する。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/c05ca263-dc13-8549-aeb0-e20654ee0700.png)

> 「[ClientProject]/wwwroot/css/app.min.css」が生成される。
> 今後スタイルシートを更新した際は、このコマンドを実行して「app.min.css」ファイルを更新する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/c9c2d126-62b4-5895-189d-4ef1c04debd5.png)

Clientプロジェクトのファイル(.csproj)をテキストエディタ等で開いて、ビルドのたびにコマンドを実行する設定を追加する。

```:追加するコード
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
  <Exec Command="npm run buildcss" />
</Target>
```
>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/a26461c4-506d-611d-3b49-594563707b24.png)
追加すると、ビルド時の出力に実行されている様子が確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/194b0936-5dee-7619-2125-50da7d9bb841.png)


「[ClientProject]/wwwroot/index.html」をtailwind仕様に書き換える。

```html:[ClientProject]/wwwroot/index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
        <title>BlazorTailwind</title>
        <base href="/" />
        <!--<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
        <link href="css/app.css" rel="stylesheet" />-->
        <link href="css/app.min.css" rel="stylesheet" />
        <link href="BlazorTailwind.Client.styles.css" rel="stylesheet" />
    </head>
    <body class="font-custom">
        <div id="app">Loading...</div>

        <div id="blazor-error-ui">
            An unhandled error has occurred.
            <a href="" class="reload">Reload</a>
            <a class="dismiss">🗙</a>
        </div>
        <script src="_framework/blazor.webassembly.js"></script>
    </body>
</html>
```

> 行ったこと
> htmlタグのlangをjaに変更
> bootstrapとapp.cssをコメントアウト
> app.min.cssを追加。

「[ClientProject]/Pages/Index.razor」にtailwindのサンプルを追記する。

```html:[ClientProject]/Pages/index.razor
@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<!-- ここから追加 -->
<div class="bg-gray-50">
    <div class="mx-auto py-12 px-4">
        <div class="mt-8 flex">
            <button class="bg-gray-500 hover:bg-purple-600 p-4 shadow-md rounded-md text-white m-10">
                Download
            </button>
            <button class="bg-gray-500 hover:bg-red-600 p-4 shadow-md rounded-md text-white m-10">
                Visit
            </button>
        </div>
    </div>
</div>
```

デバッグ実行し、DownloadとVisitボタンにスタイルが適用された状態で、以下のように表示されたら導入完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/6a39603d-4a80-0f7c-b08d-4cd709241e6b.png)
> うまく表示されない場合は、リビルド＋キャッシュを消してリトライ。
</div>
</details>

<details>
<summary>TailWindCSS用にファイル構成を変更</summary>
<div>
「[ClientProject]/Shared/MainLayout.razor」からサイドメニューを削除、中央寄せの設定「`container mx-auto`」を適用

```html:[ClientProject]/Shared/MainLayout.razor
@inherits LayoutComponentBase

<div class="page">
    <main class='container mx-auto'>
        @Body
    </main>
</div>
```

デフォルトで用意されているサンプルコードを削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/af0cf013-9afd-9a68-78e4-8dc4a0b58014.png)
> 削除するファイル
>「[ClientProject]/Pages/Counter.razor」「[ClientProject]/Pages/FetchData.razor」「[ClientProject]/Shared/NavMenu.razor」「[ClientProject]/Pages/SurveyPrompt.razor」
>「[ServerProject]/Controllers/WeatherForecastController.cs」
>「[SharedProject]/WeatherForecast.cs」

ファイルの削除に伴い、「[ClientProject]/Pages/Index.razor」を修正

```html:[ClientProject]/Pages/Index.razor
@page "/"
<PageTitle>Index</PageTitle>
```

</div>
</details>

# ログイン画面の実装
> 実装にあたり、Tailwind CSSのLoginFormテンプレートを使用します。
> https://flowrift.com/
> ■ライセンス：https://github.com/n6ai/flowrift/blob/main/LICENSE
> 　⇒ Flowrift Code License：私用・商用プロジェクト関係なくコピー・変更・配布して使用できます。

<details>
<summary>ログイン画面(デザイン)の実装</summary>
<div>

「[ClientProject]/Pages/Login.razor」を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/609abbd5-cf71-6591-c064-2d1f16e83028.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/c27a763b-5cf4-d224-0db5-bcc69e35f209.png)


デフォルトのコードをすべて消し、「`@page "/Login"`」と「`<PageTitle>ログイン</PageTitle>`」を追加。
次にFlowriftのログインフォームテンプレートを使用する。コードをコピーして貼り付ける。
> Flowrift - form(2)
> https://flowrift.com/c/form/oHxFf?view=preview
>テンプレートのコードコピーはここをクリックすれば可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/3041a71c-c418-e490-703c-0d595800ff78.png)

```html:[ClientProject]/Pages/Login.razor
@page "/Login"

<PageTitle>ログイン</PageTitle>

<div class="bg-white py-6 sm:py-8 lg:py-12">
  <div class="max-w-screen-2xl px-4 md:px-8 mx-auto">
    <h2 class="text-gray-800 text-2xl lg:text-3xl font-bold text-center mb-4 md:mb-8">Login</h2>

    <form class="max-w-lg border rounded-lg mx-auto">
      <div class="flex flex-col gap-4 p-4 md:p-8">
        <div>
          <label for="email" class="inline-block text-gray-800 text-sm sm:text-base mb-2">Email</label>
          <input name="email" class="w-full bg-gray-50 text-gray-800 border focus:ring ring-indigo-300 rounded outline-none transition duration-100 px-3 py-2" />
        </div>

        <div>
          <label for="password" class="inline-block text-gray-800 text-sm sm:text-base mb-2">Password</label>
          <input name="password" class="w-full bg-gray-50 text-gray-800 border focus:ring ring-indigo-300 rounded outline-none transition duration-100 px-3 py-2" />
        </div>

        <button class="block bg-gray-800 hover:bg-gray-700 active:bg-gray-600 focus-visible:ring ring-gray-300 text-white text-sm md:text-base font-semibold text-center rounded-lg outline-none transition duration-100 px-8 py-3">Log in</button>

        <div class="flex justify-center items-center relative">
          <span class="h-px bg-gray-300 absolute inset-x-0"></span>
          <span class="bg-white text-gray-400 text-sm relative px-4">Log in with social</span>
        </div>

        <button class="flex justify-center items-center bg-blue-500 hover:bg-blue-600 active:bg-blue-700 focus-visible:ring ring-blue-300 text-white text-sm md:text-base font-semibold text-center rounded-lg outline-none transition duration-100 gap-2 px-8 py-3">
          <svg class="w-5 h-5 shrink-0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M12 0C5.37273 0 0 5.37273 0 12C0 18.0164 4.43182 22.9838 10.2065 23.8516V15.1805H7.23764V12.0262H10.2065V9.92727C10.2065 6.45218 11.8996 4.92655 14.7878 4.92655C16.1711 4.92655 16.9025 5.02909 17.2489 5.076V7.82945H15.2787C14.0525 7.82945 13.6244 8.99182 13.6244 10.302V12.0262H17.2178L16.7302 15.1805H13.6244V23.8773C19.4815 23.0825 24 18.0747 24 12C24 5.37273 18.6273 0 12 0Z" fill="white" />
          </svg>

          Continue with Facebook
        </button>

        <button class="flex justify-center items-center bg-white hover:bg-gray-100 active:bg-gray-200 border border-gray-300 focus-visible:ring ring-gray-300 text-gray-800 text-sm md:text-base font-semibold text-center rounded-lg outline-none transition duration-100 gap-2 px-8 py-3">
          <svg class="w-5 h-5 shrink-0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M23.7449 12.27C23.7449 11.48 23.6749 10.73 23.5549 10H12.2549V14.51H18.7249C18.4349 15.99 17.5849 17.24 16.3249 18.09V21.09H20.1849C22.4449 19 23.7449 15.92 23.7449 12.27Z" fill="#4285F4" />
            <path d="M12.2549 24C15.4949 24 18.2049 22.92 20.1849 21.09L16.3249 18.09C15.2449 18.81 13.8749 19.25 12.2549 19.25C9.12492 19.25 6.47492 17.14 5.52492 14.29H1.54492V17.38C3.51492 21.3 7.56492 24 12.2549 24Z" fill="#34A853" />
            <path d="M5.52488 14.29C5.27488 13.57 5.14488 12.8 5.14488 12C5.14488 11.2 5.28488 10.43 5.52488 9.71V6.62H1.54488C0.724882 8.24 0.254883 10.06 0.254883 12C0.254883 13.94 0.724882 15.76 1.54488 17.38L5.52488 14.29Z" fill="#FBBC05" />
            <path d="M12.2549 4.75C14.0249 4.75 15.6049 5.36 16.8549 6.55L20.2749 3.13C18.2049 1.19 15.4949 0 12.2549 0C7.56492 0 3.51492 2.7 1.54492 6.62L5.52492 9.71C6.47492 6.86 9.12492 4.75 12.2549 4.75Z" fill="#EA4335" />
          </svg>

          Continue with Google
        </button>
      </div>

      <div class="flex justify-center items-center bg-gray-100 p-4">
        <p class="text-gray-500 text-sm text-center">Don't have an account? <a href="#" class="text-indigo-500 hover:text-indigo-600 active:text-indigo-700 transition duration-100">Register</a></p>
      </div>
    </form>
  </div>
</div>
```


デバッグ実行し、URLに「/Login」追記してアクセス。以下の画面が表示されればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/af649394-020d-2b93-cfd5-867302245637.png)

動作が確認できたので、使わないソーシャルログイン削除やら、日本語化やら、placeholderやらカスタマイズ調整

```html:[ClientProject]/Pages/Login.razor
@page "/Login"

<PageTitle>ログイン</PageTitle>

<div class="bg-white py-6 sm:py-8 lg:py-12">
  <div class="max-w-screen-2xl px-4 md:px-8 mx-auto">
    <h2 class="text-gray-800 text-2xl lg:text-3xl font-bold text-center mb-4 md:mb-8">Login</h2>

    <form class="max-w-lg border rounded-lg mx-auto">
      <div class="flex flex-col gap-4 p-4 md:p-8">
        <div>
          <label for="id" class="inline-block text-gray-800 text-sm sm:text-base mb-2">ログインID</label>
          <input name="id" placeholder="Account ID" class="w-full bg-gray-50 text-gray-800 border focus:ring ring-indigo-300 rounded outline-none transition duration-100 px-3 py-2" />
        </div>

        <div>
          <label for="password" class="inline-block text-gray-800 text-sm sm:text-base mb-2">パスワード</label>
          <input name="password" placeholder="Password" class="w-full bg-gray-50 text-gray-800 border focus:ring ring-indigo-300 rounded outline-none transition duration-100 px-3 py-2" />
        </div>

        <button class="block bg-gray-800 hover:bg-gray-700 active:bg-gray-600 focus-visible:ring ring-gray-300 text-white text-sm md:text-base font-semibold text-center rounded-lg outline-none transition duration-100 px-8 py-3">ログイン</button>

        <div class="flex justify-center items-center relative">
          <span class="h-px bg-gray-300 absolute inset-x-0"></span>
          <span class="bg-white text-gray-400 text-sm relative px-4">または</span>
        </div>

        <button class="flex justify-center items-center bg-blue-500 hover:bg-blue-600 active:bg-blue-700 focus-visible:ring ring-blue-300 text-white text-sm md:text-base font-semibold text-center rounded-lg outline-none transition duration-100 gap-2 px-8 py-3">
          パスワードを忘れた場合
        </button>
      </div>

      <div class="flex justify-center items-center bg-gray-100 p-4">
        <p class="text-gray-500 text-sm text-center">アカウントをお持ちでない場合は <a href="#" class="text-indigo-500 hover:text-indigo-600 active:text-indigo-700 transition duration-100">こちら</a></p>
      </div>
    </form>
  </div>
</div>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/d7ae9eea-4c58-c36c-fff8-9972cbc026f0.png)



</div>
</details>

> 認証機能はMicrosoft.AspNetCore.Components.Authorizationを使用する。
> ASP.NET Core Blazor の認証と承認
> https://docs.microsoft.com/ja-jp/aspnet/core/blazor/security/?view=aspnetcore-6.0

<details>
<summary>ログイン機能の実装</summary>
<div>

「ツール ⇒ Nugetパッケージマネージャー　⇒ ソリューションのNugetパッケージの管理」から
「`Microsoft.AspNetCore.Components.Authorization`」
「`Microsoft.AspNetCore.Authorization`」
を[ClientProject]にチェックをつけて「インストール」をクリック
> 注：安定板をインストールすること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/59104531-12ad-f45f-b388-746e30ec2883.png)
同意してインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/cfd7880f-c44e-f7e6-4d27-61471f287ec9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/1a42d4c3-838b-5e90-b468-df1b309dc634.png)
同意してインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/2c396992-6da1-f2bf-1f5f-483a4acb8632.png)

[ClientProject]/Pages/_Imports.razorに
「`@using Microsoft.AspNetCore.Components.Authorization`」
「`@using Microsoft.AspNetCore.Authorization`」
を追記

```html:_Imports.razor
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorTailwind.Client
@using BlazorTailwind.Client.Shared

@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Authorization
```

「`[ClienProject]/Pages/Index.razor.cs`」を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/0c8f2a9f-459d-02bb-f872-7d0fbac7ddfd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/2bc89b9e-bf3d-adb6-2542-eea6f25d3c58.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423799/84b138fd-3555-c5b4-fad9-cbe48b4cfa93.png)

[ClientProject]/Programs.csに以下を追加。
「`builder.Services.AddOptions();`」
「`builder.Services.AddAuthorizationCore();`」

```C#:[ClientProject]/Programs.cs

using BlazorTailwind.Client;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();
```


</div>
</details>

# 現状の課題

- ホットリロードの対応ができない。(解決済)
    - 公式フォーラムに情報があった。VS2022のバグっぽい。17.1.0 preview5をインストールして解決した。
    https://developercommunity.visualstudio.com/t/Hot-Reload-For-CSS-Not-Working-With-Blaz/1590384?space=8&q=hot+reload+css
- Blazorのエラー発生時にerror-uiを表示できない。(解決済)
    - app.cssに設定を入れれば、治るらしい。
    https://medium.com/@georgemr/tailwind-css-in-blazor-asp-net-core-app-with-grunt-24a627cd9f3a
- コンポーネントの置き場所をどう整理するかルール決め
- 認証周りの実装
    - https://qiita.com/nobu17/items/91c96ede1bd043fe1373 これで検討中(firebaseは使わないけど。)

# coming soon...

ログイン機能の実装
bUnitテストの実装