Create or review Blazor components (.razor files) with correct architecture. USE FOR: writing new Blazor components that do NOT involve JavaScript interop, implementing parameters and EventCallback, RenderFragment slots, component lifecycle (OnInitializedAsync, OnParametersSet), async patterns, IAsyncDisposable, CancellationToken, CSS isolation, code-behind. DO NOT USE FOR: creating new projects (use create-blazor-project), JavaScript interop or calling browser APIs from Blazor (use use-js-interop), forms and validation (use collect-user-input), prerendering issues (use support-prerendering),
Start a fresh conversation. Replace the highlighted placeholders.
Use author-component to create or review the Blazor component at [component path] to meet [component requirements], using idiomatic parameters, EventCallback-based events, and appropriate UI states.
Required inputs
[component path]
[component requirements]
User-approved starter prompt based on a pinned source version; check current skill requirements before running. Task evidence ↗
SKILL.md
license: MITname: author-componentdescription: > Create or review Blazor components (.razor files) with correct architecture. USE FOR: writing new Blazor components that do NOT involve JavaScript interop, implementing parameters and EventCallback, RenderFragment slots, component lifecycle (OnInitializedAsync, OnParametersSet), async patterns, IAsyncDisposable, CancellationToken, CSS isolation, code-behind. DO NOT USE FOR: creating new projects (use create-blazor-project), JavaScript interop or calling browser APIs from Blazor (use use-js-interop), forms and validation (use collect-user-input), prerendering issues (use support-prerendering), HTTP data fetching patterns (use fetch-and-send-data), coordinating state between unrelated components (use coordinate-components).
Author Blazor Component
Core Rules
Data flows down via [Parameter]. Events flow up via EventCallback<T> (never Action/Func).
Never mutate [Parameter] properties. Copy to a private field in OnParametersSet.
Use [Parameter] public T Prop { get; set; } — never required or init (causes BL0007).
Use [EditorRequired] for required parameters.
Handle all states: loading, empty, loaded, error — each with @if/@else.
Use @key on repeated elements in loops for efficient diffing.
Use IReadOnlyList<T> (not IEnumerable<T>) for collection parameters.
RenderFragment & Generics
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment<TItem>? RowTemplate { get; set; } // generic template
Use @typeparam TItem for generic components.
File Patterns
Single-file:.razor with @code block when logic < ~50 lines.
Code-behind:.razor + .razor.cs with partial class when logic > ~50 lines.
Disposal
Implement IAsyncDisposable (not IDisposable) when the component owns subscriptions, timers, or CTS.
In DisposeAsync: unsubscribe (-=), cancel CTS, dispose resources. Never call StateHasChanged.
Async Patterns
await every async operation. Never use .Result, .Wait(), Task.Run, ContinueWith, Thread.Start.
Debounce:Task.Delay + CancellationTokenSource. Cancel old CTS, create new, await delay, do work. Never use System.Threading.Timer or System.Timers.Timer.
Polling: Loop in OnInitializedAsync with await Task.Delay(interval, token) — stays on sync context.