頑張らないために頑張る

ゆるく頑張ります

「Interactivity render mode」と「Interactivity location」とは何か

Posted at — Aug 26, 2025

概要

.NET 8 からの Blazor Web App テンプレートには、作成ウィザードで Interactivity render mode(どの相互運用モードを有効にするか)と Interactivity location(どこにそのモードを適用するか)という2つの重要な設定があります。

alt text

上記のスクショはその作成ウィザードです。日本語化されているためなんだか妙な感じですが、「インタラクティビティ型」が「Interactivity render mode」に、「インタラクティビティ場所」が「Interactivity location」に相当します。単純に直訳しただけじゃん・・・。

この記事では、その概要と仕組み、選択肢ごとの動作や注意点・実装例をまとめます。

Blazor の「レンダーモード」とは

Blazor Web App(.NET 8 以降)では、各 Razor コンポーネントが「レンダーモード」を持ちます。これにより「どこで(サーバー/クライアント)」「どの方式で(静的/対話)」描画・イベント処理するかを柔軟に切り替えられます。

モード 説明 レンダー場所 インタラクティブ
Static Server 静的 SSR(HTML をサーバーで描画して返すのみ) サーバー いいえ
Interactive Server Blazor Server による対話的 SSR サーバー はい
Interactive WebAssembly Blazor WebAssembly によるクライアント側描画(CSR) クライアント はい
Interactive Auto 初回は Server、以降は WASM(バンドル取得後に CSR) サーバー→クライアント はい

なお、対話コンポーネントでは 既定でプレレンダリング(prerendering)有効です。必要ならオフにもできます(一部の例外やWASMのみの構成など、手動調整が必要な場合もあります)。

2つの設定が意味するもの

1) Interactivity render mode:どのモードを「サポート」するか

ウィザードで None / Server / WebAssembly / Auto を選びます。これは「プロジェクトにどの相互運用モードの“配線”を入れるか」を決めます。生成されるコードやサービス登録・プロジェクト構成が変わります。

CLI では --interactivity-int)で同等の設定が可能です。

2) Interactivity location:どこに適用するか

GlobalPer page/component の 2 択です。これは「レンダーモードの“適用範囲”」を意味します。

なお App(ルートコンポーネント)自体には @rendermode を直接付与できませんが、通常は RoutesHeadOutlet などApp配下のルート要素に指定します(Visual Studio 2022/.NET 8 テンプレートの既定通り)。

備考:「対話化」とは

ここで言う 「対話化」 とは、レンダリング後もコンポーネントを生かして、ブラウザの DOM イベント(クリック、入力、変更など)と C# の処理が連携する状態を指します。

という形でイベント処理・状態管理を継続します。

以下、何をしたら「対話化」になるのかを、具体的な実装単位でまとめます。

1) 「対話化」の最小実装(Per page/component)

宣言的に @rendermode を付けるだけで、そのページ/コンポーネントが対話化されます。Program.cs 側には対応するモードのサービス登録が必要です。

例:カウンターページを対話化(サーバー)
@page "/counter"
@rendermode InteractiveServer   <!-- ← これが“対話化”の指定 -->

<h1>Counter</h1>
<p>Count: @count</p>
<button class="btn btn-primary" @onclick="Increment">Add</button>

@code {
    int count = 0;
    void Increment() => count++;
}
// Program.cs(サーバー)
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();
例:一部コンポーネントのみ対話化(ページの中で)
<!-- ページ自体は静的SSRのまま、ボタン部分だけ対話化 -->
<InteractivePanel @rendermode="InteractiveServer" />

@rendermodeページ定義(上部)にもコンポーネント呼び出し(インスタンス)にも書けます。前者は静的インスタンス、後者は任意のモードを個別に割り当て可能です。

2) アプリ全体を「対話化」(Global)

Routes と HeadOutlet に @rendermode を付けると、ルーティングされるページ全体が対話化されます(Interactivity location: Global がこれ)。App そのものには指定できません。

<!-- Components/App.razor -->
<HeadOutlet @rendermode="InteractiveServer" />
<Routes     @rendermode="InteractiveServer" />

レイアウト(MainLayout)にはレンダーモードを付けられないため、レイアウト配下を全部対話にしたい場合は Global で Routes に付与するのが定石です。

3) WASM/Auto で「対話化」する場合の実装要件

// Program.cs(サーバー)
builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents();

app.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode();

4) プレレンダリング(prerender)の扱い

対話コンポーネントは 既定でプレレンダリング有効です。初期描画だけ SSR し、その後に回線確立(Server)や WASM 起動(Client)で“水和(再接続)”します。必要に応じてオフにできます。

@rendermode @(new InteractiveServerRenderMode(prerender: false))

5) よくある注意点(対話化まわりの“ハマりどころ”)

6) 「対話化」チェックリスト(実装手順のまとめ)

  1. Program.cs に該当モードを登録
    • Server: AddInteractiveServerComponents() / AddInteractiveServerRenderMode()
    • WASM: AddInteractiveWebAssemblyComponents() / AddInteractiveWebAssemblyRenderMode()
    • Auto: 上記双方を登録。
  2. 適用範囲を決める
    • GlobalComponents/App.razorRoutes / HeadOutlet@rendermode
    • Per:対象ページの先頭、または対象コンポーネントのインスタンスに @rendermode
  3. WASM/Auto の場合は .Client に配置(WASM 実行させたいコンポーネント、レイアウト、ページ)。
  4. (必要に応じ)prerender の有効/無効を調整
  5. (必要に応じ)非シリアライズ引数の見直し、ラッパー化。

一言で言えば

具体的に何が生成され、どう動くのか

生成されるコード(抜粋)

Server を有効にした場合(例):

// Program.cs(サーバー)
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

WASM を有効にした場合(例):

// Program.cs(サーバー)
builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents();

app.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode();
// テンプレートでは .Client プロジェクトも生成される

Auto を有効にした場合(例):

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode();

(上の構成は公式ガイドとテンプレートの既定パターンに準拠)

Global と Per の違い(App.razor の例)

<!-- Components/App.razor -->
<HeadOutlet @rendermode="InteractiveServer" />
<Routes     @rendermode="InteractiveServer" />

これでルーティングされるページはすべて対話化されます。

@page "/counter"
@rendermode InteractiveServer

<h1>Counter</h1>
<button class="btn btn-primary" @onclick="Increment">Add</button>

@code {
    int count = 0;
    void Increment() => count++;
}

このページだけが対話的になり、他のページは静的 SSR のままです。

「Interactivity render mode」別の効果とトレードオフ

Static Server(None を選択)

Interactive Server(Server を選択)

Interactive WebAssembly(WebAssembly を選択)

Interactive Auto(Auto を選択)

「Interactivity location」の影響と選び方

Global を選ぶ場合

Per page/component を選ぶ場合

実務でよく使うパターンとコード断片

1) アプリ全体を Interactive Server(Global)

<!-- Components/App.razor -->
<HeadOutlet @rendermode="InteractiveServer" />
<Routes     @rendermode="InteractiveServer" />
// Program.cs
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
app.MapRazorComponents<App>().AddInteractiveServerRenderMode();

(ルーター経由のページにモードが伝播。App 自体に指定できない点に注意)

2) 一部ページのみ WASM(Per page/component)

@page "/chart"
@rendermode InteractiveWebAssembly
// Program.cs(サーバー)
builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents();

app.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode();

// .Client プロジェクトを含め、対象コンポーネントは Client 側でビルド

(WASM コンポーネントは Client プロジェクトに置く)

3) Auto(初回 Server → 以降 WASM)+ 状態設計の注意

Auto を使うと最初はサーバー実行、以降はWASM 実行に切り替わるため、DB アクセス等は抽象化して WASM では API 経由に統一すると破綻しにくいです。Server側の状態がWASM側に自動で引き継がれるわけではありません。

どれを選ぶべきか

具体的なユースケースを考えてみます。

1. 社内システム(イントラネット・業務アプリ)

2. パブリックな Web サイト(SEO 重視・情報提供中心)

3. Web アプリ(SaaS・外部ユーザー向け)

4. PWA(オフライン対応・モバイル重視)

まとめ表

ユースケース Render Mode Location
社内システム Interactive Server Global
パブリックサイト Static + Interactive Server (一部) Per page/component
Web アプリ Interactive Auto Global
PWA Interactive WASM Global

よくあるつまずき

Visual Studio/CLI での設定対応

  dotnet new blazor \
    --interactivity Server|WebAssembly|Auto|None \
    --all-interactive true|false

--interactivity がモード、--all-interactive が Global/Per の切り替え)

まとめ

なかなか選択肢が多くてメンドクサイ大変ですが、要点は以下の通りです。

参考

  1. ASP.NET Core Blazor のレンダー モード
  2. .NET 8 の Blazor で静的 SSR と InteractveServer/WASM 間の状態渡し
  3. What does ‘interactivity location’ mean when creating a Blazor App from a template?
comments powered by Disqus