April 15, 2025
When building UI with Blazor, every data-fetching async call leaves you sprinkling if (data == null)
or if (!IsLoaded)
around the page.It bloats markup, hides the real UI, and is easy to forget in a big component tree.
Whole-page “Loading…” screens block the user even when 90% of the page is ready.
Approach | Upside | Downside |
Inline if checks | Simple | Repetition + noisy markup |
Global “splash” page | Easy to add | Users stare at a spinner instead of usable UI |
Skeleton loaders | Great UX | You still need the trigger logic everywhere |
A loading guard is a tiny wrapper component that:
No more null-checks, and you can wrap only the parts of the page that truly depend on a given slice of state.
<!-- LoadGuard.razor -->
@if (When())
{
@ChildContent
}
else
{
@Placeholder
}
@code {
[Parameter] public required Func<bool> When { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment? Placeholder { get; set; }
}
Usage:
<LoadGuard When="@(() => OrdersState.Value.IsLoaded)">
<OrdersTable />
</LoadGuard>
Add a custom placeholder when you need more than a spinner:
<LoadGuard When="@(() => OrdersState.Value.IsLoaded)">
<OrdersTable />
<Placeholder>
<RadzenSkeleton Count="5" />
</Placeholder>
</LoadGuard>
A named guard documents intent and avoids long lambda expressions in markup.
<!-- Frazor -->
@inherits FluxorComponent
@if (CoreUiState.Value.FinancialYearsLoaded)
{
@ChildContent
}
else
{
<RadzenProgressBar Mode="Indeterminate" />
}
@code {
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Inject] public required IState<CoreUiState> CoreUiState { get; set; }
}
Usage:
<FinancialYearLoadingGuard>
<FinancialYearSelector />
<BalanceSheet />
</FinancialYearLoadingGuard>
Benefits:
These work great with Fluxor (but don't require it) - Fluxor gives you a single source of truth (IState<T>
) and a clean IsLoaded
flag—perfect for a guard.
Without Fluxor, just expose a bool IsReady
from your service and bind it to When
.
CustomerGuard
, PermissionsGuard
) for readability.Loading guards cut boilerplate, improve perceived performance, and make your Blazor pages declarative:
<PermissionsGuard>
<DeleteButton />
</PermissionsGuard>
<WeatherGuard>
<ForecastChart />
</WeatherGuard>
No more scattered null-checks—just clean, readable markup that lights up as data arrives. Happy guarding! 😎
Loading guards are a simple but powerful pattern for improving reliability and user experience in Blazor apps. By preventing premature UI actions, you can avoid many common bugs and make your app feel more polished.
Have you used loading guards in your Blazor projects? Share your experience in the comments!