| name | blazor-ui |
| description | Build and debug ABP Blazor UI — pages/components, base classes, render/hosting models, theming, and the Blazorise vs MudBlazor choice. USE FOR: creating Blazor pages/components, choosing a base class (AbpComponentBase / AbpCrudPageBase), calling application services from Blazor, picking a hosting/render model (Server / WebAssembly / WebApp / Auto), working with the LeptonX/Basic theme, deciding between Blazorise and MudBlazor components. DO NOT USE FOR: Angular UI (use angular-ui), MVC / Razor Pages UI (use mvc-razor-ui), menu contribution and localization resources/json (use menus-and-localization), permission definitions on the backend (use permissions-and-authorization).
|
| license | MIT |
ABP Blazor UI
Guidance for building UI on top of ABP's Blazor stack. The core component APIs (e.g. AbpComponentBase) come from Volo.Abp.AspNetCore.Components.*; the Blazorise CRUD base classes (AbpCrudPageBase) come from Volo.Abp.BlazoriseUI.
When to Use
- Creating or debugging Blazor pages/components in an ABP app.
- Choosing a base class (
AbpComponentBase for custom pages, AbpCrudPageBase for CRUD screens).
- Calling application services from Blazor (in-process or over the dynamic HTTP client proxies).
- Picking a hosting/render model: Blazor Server, WebAssembly, or the .NET 8+ Blazor WebApp / Auto render modes.
- Working with the LeptonX or Basic theme, or deciding between the Blazorise and MudBlazor component libraries.
When Not to Use
- Angular UI — use the angular-ui skill.
- MVC / Razor Pages UI (
abp-* tag helpers, AbpPageModel) — use the mvc-razor-ui skill.
- Contributing menu items or defining localization resources/json — use the menus-and-localization skill.
- Defining backend permissions — use the permissions-and-authorization skill.
Component base classes
Inherit your .razor components / code-behind from ABP base classes to get injected framework services for free.
AbpComponentBase (namespace Volo.Abp.AspNetCore.Components) is the root base. It derives from OwningComponentBase, so it owns a DI scope. It exposes protected members you should reuse instead of re-injecting:
L — an IStringLocalizer (see LocalizationResource, below).
Logger, LoggerFactory
CurrentUser (ICurrentUser), CurrentTenant (ICurrentTenant)
AuthorizationService (IAuthorizationService)
Message (IUiMessageService), Notify (IUiNotificationService), Alerts
ObjectMapper, Clock
HandleErrorAsync(Exception) — routes exceptions through IUserExceptionInformer.
Set LocalizationResource in your constructor / OnInitialized so L["Key"] resolves against your module's resource:
public partial class BookList : AbpComponentBase
{
public BookList()
{
LocalizationResource = typeof(MyProjectResource);
}
}
AbpCrudPageBase<TAppService, TEntityDto, TKey, ...> (in Volo.Abp.BlazoriseUI, derives from AbpComponentBase) is a generic base for list/create/edit/delete pages backed by an ICrudAppService. It wires up GetListAsync, paging, create/update modals, and delete. Use it when the page is a straightforward CRUD screen over a crud app service; drop to AbpComponentBase for custom pages.
Calling application services
Inject the application service interface (from the .Application.Contracts package) and call it directly. ABP resolves it either in-process (Blazor Server, or a monolith where the app layer runs in the same process) or over HTTP via the auto-generated dynamic C# client proxies (Blazor WebAssembly, or any client that references the HTTP API client package). Your component code is identical either way:
@inject IBookAppService BookAppService
@code {
protected override async Task OnInitializedAsync()
{
var books = await BookAppService.GetListAsync(new GetBookListInput());
}
}
The dynamic HTTP client proxies are registered by AddHttpClientProxies in the WebAssembly/client module — you don't hand-write an HTTP client.
Hosting / render models
ABP supports three Blazor models; the framework packages map to them:
- Blazor Server —
Volo.Abp.AspNetCore.Components.Server.*. Runs on the server over a SignalR circuit.
- Blazor WebAssembly (WASM) —
Volo.Abp.AspNetCore.Components.WebAssembly.*. Runs in the browser; talks to the backend through the dynamic HTTP client proxies.
- Blazor WebApp / Auto render modes — the .NET 8+ unified "Blazor Web App" host that can mix
InteractiveServer, InteractiveWebAssembly, and InteractiveAuto render modes. ABP Studio offers this as a template option.
Shared, host-agnostic pieces live in Volo.Abp.AspNetCore.Components.Web.*. There is also a MAUI Blazor host (...Components.MauiBlazor.*) for desktop/mobile.
When a component must run only on the server (e.g. direct DbContext access), keep it out of WASM-rendered paths; prefer app-service calls that work under any render mode.
Theming: LeptonX vs Basic
ABP ships a Basic theme and the LeptonX theme (available as LeptonX Lite and the full LeptonX). Themes provide the layout, toolbar, menu rendering, and branding. Theme-specific Blazor bundling/theming packages live under ...Components.*.Theming and ...Components.*.Theming.MudBlazor. Menu items you contribute (see the menus-and-localization skill) are rendered by whichever theme is active.
Blazorise vs MudBlazor
ABP Studio's Blazor templates offer two component libraries:
- Blazorise — the long-standing default;
AbpCrudPageBase lives in Volo.Abp.BlazoriseUI.
- MudBlazor — the alternative option; framework support is under the
...Components.*.Theming.MudBlazor packages.
They are not interchangeable at the markup level — component tags, layout primitives, and dialog/modal APIs differ. Before editing or generating a Blazor screen, confirm which library the project uses, and match existing components in that library rather than mixing the two.
Where pages/components live
Pages and components live in the Blazor host/UI project (e.g. *.Blazor, or the .Client project for WebApp/WASM-rendered components), typically under Pages/ and Components/. Reusable module UI ships in module *.Blazor packages. Follow the existing folder layout of the project.
Validation
- The Blazor host builds and runs; a page inheriting
AbpComponentBase compiles and its injected members (L, CurrentUser, Message, …) resolve at runtime without manual injection.
L["Key"] renders the localized value (not the raw key) once LocalizationResource is set to your module's resource.
- App-service calls return data under any render mode — the same component works whether resolved in-process (Server) or over the dynamic HTTP client proxies (WASM).
Common Pitfalls
- Mixing Blazorise and MudBlazor — the two libraries are not markup-compatible; component tags, layout primitives, and dialog/modal APIs differ. Confirm which library the project uses and match existing components rather than mixing the two.
- Running server-only code in a WASM-rendered path — a component that needs direct DbContext access must stay out of WASM-rendered paths; prefer app-service calls that work under any render mode.
- Forgetting to set
LocalizationResource — without it, L["Key"] won't resolve against your module's resource.
- Re-injecting framework services — reuse the protected members on the base class (
L, Logger, CurrentUser, Message, Notify, ObjectMapper, Clock, …) instead of injecting them again.