Blazor Interview Questions and Answers (2026)
Blazor interview questions usually center on one core decision — Server vs WebAssembly — and how that choice ripples through everything else: component lifecycle, dependency injection scope, and how state and JS interop behave differently under each hosting model. Here are the ones that come up most.
-
What's the difference between Blazor Server and Blazor WebAssembly?
Blazor Server runs your component code entirely on the server; the browser holds a thin client that renders a DOM diff sent over a persistent SignalR connection, and every UI interaction is sent back to the server over that connection for processing. Blazor WebAssembly downloads the compiled .NET runtime and your app's assemblies to the browser via WebAssembly, then runs entirely client-side with no ongoing server dependency for UI logic. Server offers fast initial load, full .NET/server-resource access, and small download size, but requires a constant low-latency connection and doesn't scale per-server as well since server memory is held per active circuit. WebAssembly offers offline capability and reduced server load after initial download, but has a heavier initial payload and, historically, slower cold-start due to runtime download and JIT/interpreter execution (mitigated by AOT compilation).
-
What are the Blazor component lifecycle methods, and in what order do they run?
On initial render: the constructor runs, parameters are set (
SetParametersAsync), thenOnInitialized/OnInitializedAsyncruns once, followed byOnParametersSet/OnParametersSetAsync, then the component renders (BuildRenderTree), and finallyOnAfterRender/OnAfterRenderAsyncruns after the component's markup is added to the DOM (useful for JS interop that needs the actual rendered elements). On subsequent updates (e.g., a parent re-renders and passes new parameters), onlyOnParametersSet(Async)and the render/OnAfterRendersteps re-run —OnInitializednever runs again for the same component instance.OnAfterRenderreceives afirstRenderboolean so you can run one-time DOM-dependent setup (like initializing a JS chart library) only once. -
How does `@bind` work in Blazor, and how do you customize it?
@bindis compiler sugar that expands to both a value assignment and a change event handler —<input @bind="Name" />on a text input expands roughly to settingvaluefromNameand wiringonchangeto updateName. By default it usesonchange(fires on blur/Enter), but you can specify@bind:event="oninput"to update on every keystroke instead.@bind:formatlets you specify a display format for values like dates. For custom components, you implement two-way binding by exposing aValueparameter plus a matchingValueChangedEventCallback<T>(and typically aValueExpressionfor validation support), following Blazor's naming convention so@bind-Value="SomeProp"works on your own components exactly like built-in ones.<input @bind="Name" @bind:event="oninput" /> @code { private string Name = ""; } -
What's the difference between `[Parameter]` and `[CascadingParameter]`?
[Parameter]properties are set explicitly by a parent component passing values through attributes in markup (<ChildComponent Title="Hello" />), requiring every intermediate component in the tree to pass the value down manually if a deeply nested descendant needs it.[CascadingParameter]receives a value from the nearest ancestor<CascadingValue>in the render tree automatically, without every intermediate component needing to know about or re-declare it — useful for cross-cutting concerns like theme, current user/auth state, or a shared form'sEditContext. Cascading parameters trade explicitness for convenience: they make data flow implicit and can be harder to trace, so they're best reserved for genuinely cross-cutting values rather than as a general substitute for normal parameter passing. -
How does dependency injection work in Blazor, and are lifetimes the same as ASP.NET Core?
Services are registered the same way, via
builder.Services.AddScoped/AddSingleton/AddTransientinProgram.cs, and injected into components with@inject IMyService MyService(which is sugar for a property with[Inject]). The lifetime semantics differ subtly by hosting model: in Blazor Server, a "scope" corresponds to a user's SignalR circuit (roughly, one browser tab session) rather than one HTTP request, so a scoped service persists for the whole duration that circuit is connected — much longer-lived than a typical ASP.NET Core scoped request. In Blazor WebAssembly, everything effectively runs in a single client-side scope since there's no server request boundary, so scoped and singleton behave almost identically within one browser session. This distinction matters for state leakage — a "scoped" service in Blazor Server can inadvertently hold state across many user interactions within a session. -
What is JS interop, and how do you call JavaScript from Blazor (and vice versa)?
JS interop lets Blazor call JavaScript functions and JavaScript call back into .NET, necessary for browser APIs Blazor doesn't wrap (localStorage, canvas, third-party JS libraries, file downloads). You inject
IJSRuntimeand callInvokeAsync<T>("functionName", args)to invoke a JS function defined in a loaded script. For JS-to-.NET calls, you pass aDotNetObjectReferencewrapping a component instance, and JS calls back viaDotNet.invokeMethodAsync, targeting a .NET method marked[JSInvokable]. Blazor WebAssembly also supports synchronous JS interop (IJSInProcessRuntime) since there's no network round-trip, whereas Blazor Server calls are always asynchronous since they cross the SignalR connection. Excess JS interop calls in Blazor Server can hurt performance due to per-call network latency, so batching/minimizing round-trips matters more there than in WASM.await JSRuntime.InvokeVoidAsync("console.log", "Hello from Blazor"); -
What is `EventCallback`, and why does Blazor prefer it over plain delegates for component events?
EventCallback(andEventCallback<T>) is Blazor's wrapper for exposing component "events" as parameters that a parent can bind a handler to (<Child OnSave="HandleSave" />), used instead of rawAction/EventHandlerdelegates because it integrates with Blazor's rendering system — invoking anEventCallbackautomatically triggers a re-render of the component that owns the handler (and correctly propagates exceptions and async completion), which a plain delegate invocation wouldn't reliably do without manualStateHasChanged()calls. It also supports async handlers naturally (EventCallbackwraps aTask-returning delegate), so a parent'sasync Task HandleSave()method just works when invoked by the child, with the child able to await the whole handler's completion if needed.[Parameter] public EventCallback<string> OnSave { get; set; } private async Task Submit() => await OnSave.InvokeAsync(Name); -
What is a `RenderFragment`, and how do child content and templated components use it?
RenderFragmentis a delegate type representing a chunk of UI markup that can be passed around and rendered later, essentially Blazor's version of a "UI as a value" — it's what backsChildContent, the implicit parameter that captures whatever markup is nested inside a component's tags (<MyCard>Some content</MyCard>).RenderFragment<T>is a generic version that takes a context parameter, enabling templated components where the parent supplies a template referencing data the child provides — e.g., a generic<Grid>component exposing aRowTemplateparameter of typeRenderFragment<RowData>so each consumer customizes row rendering while the grid controls iteration. This is how components like built-in<AuthorizeView>(withAuthorized/NotAuthorizedtemplates) or custom generic list/grid components let the caller inject arbitrary markup parameterized by runtime data. -
What are the common approaches to state management in Blazor?
For state scoped to a single component tree, cascading parameters or simply passing state down via normal parameters suffices. For state shared across otherwise-unrelated components (e.g., a shopping cart accessible from header and page components), a common pattern is a scoped or singleton injectable "state container" service that raises a
StateChanged/OnChangeevent, which subscribing components handle by callingStateHasChanged(). For persisting state across page navigations or reloads, options include browser storage via JS interop (localStorage/sessionStorage), or in Blazor Server, keeping it server-side in the scoped DI container tied to the circuit. Larger apps sometimes adopt Flux/Redux-style libraries (e.g., Fluxor) for more structured, predictable state updates, though a simple injectable state service is sufficient for most line-of-business apps. -
What role does SignalR play in Blazor Server?
Blazor Server uses a persistent SignalR connection (typically WebSockets, falling back to Server-Sent Events or long polling) as the transport between the browser and server: user interactions (clicks, input) are serialized and sent to the server, the server re-executes the relevant component logic against its in-memory render tree, computes a UI diff, and sends that diff back to the browser's lightweight JS client to patch the real DOM — no full page reload and minimal data transferred (just the diff, not full HTML). This is why Blazor Server requires a stable, low-latency connection to feel responsive, and why connection loss (e.g., a mobile client on a flaky network) visibly disrupts the app until it reconnects, potentially losing in-memory circuit state if the reconnect window expires.
-
How does routing work in Blazor?
Routable components declare their own routes via the
@pagedirective at the top of the component (@page "/products/{id:int}"), and theRoutercomponent inApp.razorscans the specified assembly for all components with@pagedirectives to build the route table at app startup, matching the current URL against them client-side (no full server round-trip per navigation, even in Blazor Server). Route parameters are captured into component parameters matching the route segment names, optionally with type constraints ({id:int}). Navigation between routable components is handled byNavigationManager.NavigateTo(...)or<NavLink>(which also applies an "active" CSS class automatically), and since routing is handled client-side by the Blazor runtime, navigating between Blazor pages doesn't trigger a full browser page reload, preserving app/circuit state where applicable. -
What are the key performance considerations for choosing between Blazor hosting models?
Blazor Server has near-instant initial load (just a small bootstrap script, not the whole runtime) but each UI interaction incurs network round-trip latency and consumes server memory/CPU per active circuit, which limits how many concurrent users a given server can comfortably host and makes it unsuitable for high-latency or offline scenarios. Blazor WebAssembly has a larger initial download (the .NET runtime plus app assemblies, though trimming and Brotli compression mitigate this, and .NET 8+ supports AOT compilation for near-native execution speed at the cost of larger payload) but then runs entirely client-side with no per-interaction server round-trip and no per-user server resource cost, scaling better for large concurrent audiences. A newer hybrid, "Blazor United"/render-mode-per-component in .NET 8+, lets you mix server-side rendering, static SSR, and interactive Server/WebAssembly per component, letting you choose the right tradeoff granularly rather than app-wide.
Practicing for a real interview? Get live AI help with your answers, in the browser, free to start.
Start a free session