Skip to content
cccskills
FreePublished on GitHub

dotnet-blazor

Build and review Blazor applications across server, WebAssembly, web app, and hybrid scenarios with correct component design, state flow, rendering, and hosting choices.

The English summary is being prepared. Showing the original description.

See how to install

Files included (4)

  • SKILL.md6.9 KB
  • manifest.json101 B
  • references/anti-patterns.md13.5 KB
  • references/patterns.md15.6 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Blazor

Trigger On

  • building interactive web UIs with C# instead of JavaScript
  • choosing between Server, WebAssembly, or Auto render modes
  • designing component hierarchies and state management
  • handling prerendering and hydration
  • integrating with JavaScript when necessary

Documentation

References

  • patterns.md - Detailed component patterns, state management strategies, and JS interop techniques
  • anti-patterns.md - Common Blazor mistakes and how to avoid them

Render Modes (.NET 8+)

ModeWhere It RunsBest For
StaticServer (no interactivity)SEO pages, marketing content
InteractiveServerServer via SignalRReal-time apps, thin clients
InteractiveWebAssemblyBrowser via WASMOffline-capable, client-heavy
InteractiveAutoServer first, then WASMBest of both worlds

Applying Render Modes

@* Per-component *@
@rendermode InteractiveServer

@* Or in App.razor for global *@
<Routes @rendermode="InteractiveAuto" />

InteractiveAuto Architecture

First Request:
  Browser → Server (Interactive Server) → Fast response

Subsequent Requests:
  Browser → WASM (downloaded in background) → No server needed

Workflow

  1. Choose render mode based on requirements:

    • Need SEO? Start with Static or prerendering
    • Need real-time? Use InteractiveServer
    • Need offline? Use InteractiveWebAssembly
    • Want both? Use InteractiveAuto
  2. Design components for reusability:

    • Small, focused components
    • Parameters for customization
    • Events for communication
  3. Handle state correctly:

    • Component state lives in component
    • Shared state via services (DI)
    • Persist state across prerender with [PersistentState]
  4. Validate in both environments (for Auto mode)

Component Patterns

Basic Component

@* Counter.razor *@
<button @onclick="IncrementCount">
    Clicked @count times
</button>

@code {
    private int count = 0;

    [Parameter]
    public int InitialCount { get; set; } = 0;

    protected override void OnInitialized()
    {
        count = InitialCount;
    }

    private void IncrementCount() => count++;
}

Parameter and Event Callbacks

@* Parent.razor *@
<ChildComponent Value="@value" ValueChanged="@OnValueChanged" />

@* ChildComponent.razor *@
@code {
    [Parameter] public string Value { get; set; } = "";
    [Parameter] public EventCallback<string> ValueChanged { get; set; }

    private async Task UpdateValue(string newValue)
    {
        await ValueChanged.InvokeAsync(newValue);
    }
}

State Persistence (.NET 8+)

@* Prevents double-fetch during prerender + hydration *@
@code {
    [PersistentState]
    public List<Product> Products { get; set; } = [];

    protected override async Task OnInitializedAsync()
    {
        // Only fetches once, persisted across prerender
        Products ??= await Http.GetFromJsonAsync<List<Product>>("api/products");
    }
}

Data Access Pattern for Auto Mode

// Shared interface
public interface IProductService
{
    Task<List<Product>> GetProductsAsync();
}

// Server implementation (direct DB access)
public class ServerProductService : IProductService
{
    private readonly AppDbContext _db;
    public async Task<List<Product>> GetProductsAsync()
        => await _db.Products.ToListAsync();
}

// Client implementation (HTTP call)
public class ClientProductService : IProductService
{
    private readonly HttpClient _http;
    public async Task<List<Product>> GetProductsAsync()
        => await _http.GetFromJsonAsync<List<Product>>("api/products");
}

// Registration
// Server: builder.Services.AddScoped<IProductService, ServerProductService>();
// Client: builder.Services.AddScoped<IProductService, ClientProductService>();

Anti-Patterns to Avoid

Anti-PatternWhy It's BadBetter Approach
Large componentsHard to maintain, slow rendersSplit into smaller components
Direct DB access in WASMNo DB in browserUse HTTP API
Ignoring ShouldRenderUnnecessary re-rendersOverride when needed
Sync JS interop in ServerBlocks SignalR circuitUse IJSRuntime async
No error boundariesOne error crashes appUse <ErrorBoundary>
Forgetting prerender stateDouble API callsUse [PersistentState]

Performance Best Practices

  1. Virtualize large lists:

    <Virtualize Items="@products" Context="product">
        <ProductCard Product="@product" />
    </Virtualize>
    
  2. Use @key for list diffing:

    @foreach (var item in items)
    {
        <ItemComponent @key="item.Id" Item="@item" />
    }
    
  3. Debounce rapid events:

    private Timer? _debounceTimer;
    
    private void OnInput(ChangeEventArgs e)
    {
        _debounceTimer?.Dispose();
        _debounceTimer = new Timer(_ => InvokeAsync(DoSearch), null, 300, Timeout.Infinite);
    }
    
  4. Lazy load assemblies (WASM):

    var assemblies = await LazyAssemblyLoader
        .LoadAssembliesAsync(["MyHeavyFeature.wasm"]);
    

JS Interop

Calling JavaScript from C#

@inject IJSRuntime JS

await JS.InvokeVoidAsync("alert", "Hello from Blazor!");
var result = await JS.InvokeAsync<string>("prompt", "Enter name:");

Calling C# from JavaScript

[JSInvokable]
public static string GetMessage() => "Hello from C#!";
DotNet.invokeMethodAsync('MyAssembly', 'GetMessage')
    .then(result => console.log(result));

Deliver

  • interactive Blazor components with appropriate render mode
  • efficient state management and data flow
  • proper handling of prerendering scenarios
  • performant list rendering with virtualization

Validate

  • components render correctly in chosen mode
  • state persists correctly across prerender/hydration
  • no unnecessary re-renders (check with browser tools)
  • JS interop works in both Server and WASM
  • error boundaries catch component failures
  • Auto mode works in both environments

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

dotnet

Free

Primary router skill for broad .NET work. Classify the repo by app model and cross-cutting concern first, then switch to the narrowest matching .NET skill instead of staying at a generic layer.

The English summary is being prepared. Showing the original description.

managedcode/PrompterOne45Updated May 9, 2026

Use a repo-root `.editorconfig` to configure free .NET analyzer and style rules. Use when a .NET repo needs rule severity, code-style options, section layout, or analyzer ownership made explicit. Nested `.editorconfig` files are allowed when they serve a clear subtree-specific purpose.

The English summary is being prepared. Showing the original description.

managedcode/PrompterOne45Updated May 9, 2026

Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging, and deployment patterns on current .NET.

The English summary is being prepared. Showing the original description.

managedcode/PrompterOne45Updated May 9, 2026

Use Biome in .NET repositories that ship Node-based frontend assets and want a fast combined formatter-linter-import organizer for JavaScript, TypeScript, CSS, JSON, GraphQL, or HTML. Use when a repo prefers a modern all-in-one CLI over a larger ESLint plus Prettier style stack.

The English summary is being prepared. Showing the original description.

managedcode/PrompterOne45Updated May 9, 2026

Use the free built-in .NET SDK analyzers and analysis levels with gradual Roslyn warning promotion. Use when a .NET repo needs first-party code analysis, `EnableNETAnalyzers`, `AnalysisLevel`, or warning-as-error policy wired into build and CI.

The English summary is being prepared. Showing the original description.

managedcode/PrompterOne45Updated May 9, 2026

Use the open-source free `CSharpier` formatter for C# and XML. Use when a .NET repo intentionally wants one opinionated formatter instead of a highly configurable `dotnet format`-driven style model.

The English summary is being prepared. Showing the original description.

managedcode/PrompterOne45Updated May 9, 2026

See all skills by managedcode

Report a problem with this skill