Blazorのインタラクティブコンポーネントにおけるプリレンダリング使用時の、データの重複読み込み、UIのちらつき、および状態の永続化に関する問題を解決します。
- GitHubスター
- 5,942
- ファイル
- 1
- 最終コミット
- 2026年11月11日
- ライセンス
- MIT
- 許可されたツール
- —
support-prerendering skillは何をしますか
support-prerenderingはAgent Skillsです。 Blazorのインタラクティブコンポーネントにおけるプリレンダリング使用時の、データの重複読み込み、UIのちらつき、および状態の永続化に関する問題を解決します。.
skillのSKILL.mdから生成された要約。
support-prerendering skill について
Blazor アプリケーションを開発する開発者は、この SKILL を使用して、静的な HTML プリレンダリングからインタラクティブなランタイムへの移行時に発生する一般的な問題を解決できます。OnInitializedAsync でのデータの重複取得、ハンドオフ中の UI のちらつき、コンポーネントがブラウザ専用の API を必要とする際に発生する null 参照例外などの、具体的な技術的課題に対処します。この SKILL は、状態の永続化を管理する方法を提供し、初期のサーバーレンダリング中に読み込まれたデータが、インタラクティブなセッション開始後も利用できるようにします。
開発者がデータの同期のために [PersistentState] 属性や PersistentComponentState サービスを実装する必要がある場合に、エージェントはこの SKILL をロードする必要があります。また、特定のコンポーネントでプリレンダリングを無効にしたり、[ExcludeFromInteractiveRouting] 属性を使用して特定のページをインタラクティブなルーティングから除外したりする場合にも使用されます。RendererInfo.IsInteractive のようなツールを活用することで、開発者はコードの実行を制御し、静的なフェーズでのエラーを防ぐことができます。この SKILL は、プロジェクトの初期セットアップや一般的なコンポーネント作成ではなく、既存のプリレンダリングに関するバグを修正することを目的としています。
エージェントができること
- 1API コールの重複防止状態の永続化を適用し、プリレンダリング中に読み込まれたデータが、インタラクティブなランタイムのアタッチ時に再取得されないようにします。
- 2特定のコンポーネントでのプリレンダリング無効化ブラウザ API への即時アクセスが必要なコンポーネントに対して、プリレンダリングをオフにします。
- 3特定のページでの HttpContext へのアクセスCookie やリクエストヘッダーへのアクセスが必要なページで、フルページリロードを強制します。
- 4インタラクティブ専用コードのガードランタイムチェックを使用して、特定のロジックがインタラクティブなランタイムのアタッチ後にのみ実行されるようにします。
skill の SKILL.md から作成されています。すべてのユースケースは、その引用と照合されています。
support-prerendering skillのインストール方法
各コマンドはskillフォルダをクライアントのskillsディレクトリにコピーします。読み込むには、クライアントを再起動するか新しいセッションを開始してください。プラグインにsupport-prerendering skillをインストールする
/plugin marketplace add dotnet/skills /plugin install dotnet-blazor@dotnet-agent-skills
Claude Codeにsupport-prerendering skillをインストールする
~/.claude/skills/support-prerendering/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering ~/.claude/skills/support-prerenderingClaude Code (project)にsupport-prerendering skillをインストールする
.claude/skills/support-prerendering/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering .claude/skills/support-prerenderingCodexにsupport-prerendering skillをインストールする
~/.agents/skills/support-prerendering/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering ~/.agents/skills/support-prerenderingGemini CLIにsupport-prerendering skillをインストールする
~/.gemini/skills/support-prerendering/SKILL.md
$ npx degit dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering ~/.gemini/skills/support-prerenderingClaude.aiにsupport-prerendering skillをインストールする
npx degit dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering support-prerendering && zip -r support-prerendering.zip support-prerendering # claude.ai → Customize → Skills → + → Create skill → Upload a skill → support-prerendering.zip
自動チェック
実行日 2026年11月15日完全なレポート →自動チェックに合格しました。これはセキュリティ監査ではありません。エージェントに実行させる前にスクリプトを読んでください。 チェックの仕組み
- ソースリポジトリがリンクされており、アクセス可能dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering is public and reachablegithub.com/dotnet/skills/tree/HEAD/plugins/dotnet-blazor/ski ↗合格
- オープンソースライセンス (OSI)MITspdx.org/licenses/MIT.html ↗合格
- 過去1年以内にコミットまたはリリースありLast commit 2026-11-11github.com/dotnet/skills/commits ↗合格
- スクリプトにダウンロード実行や認証情報の窃取がないNo scripts in the skill folder合格
- SKILL.md に隠れた指示がないNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/dotnet/skills/blob/HEAD/plugins/dotnet-blazor/ski ↗合格
- 事前許可ツールが限定されているNo pre-approved tools; the agent asks before using onegithub.com/dotnet/skills/blob/HEAD/plugins/dotnet-blazor/ski ↗合格
- SKILL.md が Agent Skills の形式に従っているValid name and description; says when to use it; 217 linesgithub.com/dotnet/skills/blob/HEAD/plugins/dotnet-blazor/ski ↗合格
SKILL.md
GitHubで表示Support Prerendering
How Prerendering Works
Prerendering is on by default for all interactive render modes. The server renders the component as static HTML and ships it to the browser immediately. Then the interactive runtime (Server/WebAssembly) loads and re-renders the component with full interactivity.
This means:
OnInitializedAsyncruns twice — once during prerender (static), once when the interactive runtime attaches.OnAfterRenderAsyncis NOT called during prerender — only after the interactive render.- Internal navigation between interactive pages (interactive routing) skips prerendering — prerendering only happens on full page loads.
Step 1 — Read the Project's AGENTS.md
Check the project's AGENTS.md for the Interactivity Mode and Interactivity Scope:
| Mode | Prerendering applies? |
|---|---|
| None (Static SSR) | No — there's no interactive handoff |
| Server | Yes |
| WebAssembly | Yes |
| Auto | Yes |
If the mode is None, this skill doesn't apply.
Persist State Across Prerender → Interactive
The most common prerendering problem: data loaded in OnInitializedAsync during prerender is thrown away and re-fetched when the interactive runtime attaches. This causes flicker and duplicate API/DB calls.
Recommended: [PersistentState] attribute
Annotate properties to automatically serialize during prerender and restore on interactive activation:
@page "/forecasts"
@rendermode InteractiveServer
<h1>Weather</h1>
@if (Forecasts is null)
{
<p>Loading...</p>
}
else
{
@foreach (var f in Forecasts)
{
<p>@f.Date: @f.TemperatureC°C</p>
}
}
@code {
[PersistentState]
public WeatherForecast[]? Forecasts { get; set; }
protected override async Task OnInitializedAsync()
{
Forecasts ??= await ForecastService.GetForecastsAsync();
}
}
The ??= pattern is critical — it means "only fetch if the property wasn't already restored from prerender state."
Multiple instances of the same component
When the same component type appears multiple times, use @key to disambiguate state:
@foreach (var item in items)
{
<ItemCard @key="item.Id" />
}
Advanced: PersistentComponentState service
For complex scenarios (dynamic keys, custom serialization), use the imperative API:
@inject PersistentComponentState ApplicationState
@code {
private List<Order>? orders;
protected override async Task OnInitializedAsync()
{
ApplicationState.RegisterOnPersisting(PersistOrders);
if (!ApplicationState.TryTakeFromJson<List<Order>>("orders", out var restored))
{
orders = await OrderService.GetOrdersAsync();
}
else
{
orders = restored;
}
}
private Task PersistOrders()
{
ApplicationState.PersistAsJson("orders", orders);
return Task.CompletedTask;
}
}
Disable Prerendering
Disable prerendering when a component depends on browser APIs immediately or when the prerender+interactive double render causes problems you can't solve with [PersistentState].
On a component definition
@rendermode @(new InteractiveServerRenderMode(prerender: false))
Replace InteractiveServerRenderMode with InteractiveWebAssemblyRenderMode or InteractiveAutoRenderMode as needed.
On a component instance
<MyChart @rendermode="new InteractiveServerRenderMode(prerender: false)" />
On the entire app
In App.razor:
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Note: A parent's prerendering setting overrides children. If <Routes> disables prerendering, individual pages cannot re-enable it.
Exclude Pages from Interactive Routing
In a globally interactive app, some pages may need HttpContext (cookies, request headers, response status codes). These pages must render via static SSR, not inside the interactive runtime.
Use [ExcludeFromInteractiveRouting]:
@page "/privacy"
@attribute [ExcludeFromInteractiveRouting]
<h1>Privacy Policy</h1>
This forces a full page reload when navigating to this page, exiting interactive routing. The page renders as static SSR with full HttpContext access.
In App.razor, conditionally apply the render mode:
<!DOCTYPE html>
<html>
<head>
<HeadOutlet @rendermode="RenderModeForPage" />
</head>
<body>
<Routes @rendermode="RenderModeForPage" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
@code {
[CascadingParameter]
public HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;
}
Replace InteractiveServer with the app's configured render mode.
Detect Prerender vs Interactive at Runtime
Use RendererInfo to guard code that should only run interactively:
protected override async Task OnInitializedAsync()
{
if (RendererInfo.IsInteractive)
{
// Only runs during the interactive render, not during prerender
await StartSignalRConnection();
}
}
RendererInfo properties:
IsInteractive—falseduring prerender,trueafter interactive runtime attachesName—"Static"during prerender,"Server"or"WebAssembly"when interactive
Client Services Fail During Prerender
Components in the .Client project prerender on the server. Services registered only in the client Program.cs (e.g., IWebAssemblyHostEnvironment) won't be available during prerender.
Fix by one of:
- Register a matching service on the server — both
Program.csfiles provide the service - Make the service optional — use constructor injection with a nullable default:
public MyComponent(IMyService? svc = null) - Create a service abstraction — interface in
.Client, implementations in both projects - Disable prerendering for that component
Don'ts
- Don't call JS interop in
OnInitializedAsync— JS isn't available during prerender. UseOnAfterRenderAsync(firstRender). - Don't assume
OnInitializedAsyncruns once — it runs twice with prerendering. Always use[PersistentState]or??=guards. - Don't use
HttpContextin interactive components — it's only available during the static prerender, not during the interactive lifetime. Use[ExcludeFromInteractiveRouting]for pages that need it. - Don't disable prerendering as a first resort — it hurts perceived load time and SEO. Use
[PersistentState]to preserve state instead.
このスキルのファイル
1support-prerendering skillに関する質問
Claude Codeにsupport-prerendering skillをインストールするには
npx degit dotnet/skills/plugins/dotnet-blazor/skills/support-prerendering ~/.claude/skills/support-prerenderingを実行してください。Claude Codeは~/.claude/skills(すべてのプロジェクト)または.claude/skills(単一プロジェクト)からskillsを読み込み、説明がタスクに一致する場合にskillを使用します。
support-prerendering skillはどのクライアントで使用できますか
Agent Skills形式を読み込むすべてのクライアントで使用できます: Claude Code、Codex、Gemini CLI、claude.ai(ZIPとしてアップロード)。skill内のスクリプトは、クライアントがコード実行を許可した場合にのみ実行されます。
プリレンダリング中のデータの重複取得を防ぐにはどうすればよいですか?
プロパティに [PersistentState] 属性を使用するか、PersistentComponentState サービスを使用して、プリレンダリング中にデータをシリアル化し、インタラクティブなランタイムがアタッチされたときに復元します。
特定のコンポーネントでプリレンダリングを無効にできますか?
はい、@rendermode @(new InteractiveServerRenderMode(prerender: false)) のように、prerender パラメータを false に設定したレンダーモードを指定することで無効にできます。
OnInitializedAsync 中に JS interop が失敗するのはなぜですか?
プリレンダリングのフェーズでは JavaScript が利用できないためです。JS interop の呼び出しは OnAfterRenderAsync メソッドに移動する必要があります。