Intent.Blazor
Blazor is a modern web framework from Microsoft that enables you to build rich, interactive web UIs using C# instead of JavaScript. It runs on WebAssembly (Blazor WebAssembly) or on the server via SignalR (Blazor Server), allowing you to share code and libraries across your client and server.
This module generates the foundational Blazor configuration and functionality for your application. Additional modules, such as Intent.Modules.Blazor.Components.MudBlazor, can then be used to realize the UI design as code.
Default Home Page
The first time the modelled Home page is generated, this module seeds it with a styled landing page — a hero section and a set of quick-link tiles pointing at the Intent Architect documentation, tutorials and GitHub — along with a co-located Home.razor.css for its scoped styles. Both files are written once off: on every subsequent Software Factory run they are left exactly as you have edited them, and deleting a file regenerates the default.
This applies to all render modes (Interactive Server, Interactive WebAssembly and Interactive Auto). The page uses only the theme classes this module already ships (ux-base.css / ux-components.css), so it renders correctly in both light and dark mode.
💡 When a component-library module such as Intent.Modules.Blazor.Components.MudBlazor is installed, this module stands down and the component library seeds its own home page instead.
Default Layout
The first time a modelled Layout's MainLayout.razor is generated, this module composes it from that Layout's regions: <MainLayoutHeader /> and <MainLayoutSider /> are always referenced, and <MainLayoutFooter /> is referenced when a Footer is modeled, wrapped in a ux-app-shell / ux-app-content shell that uses the theme classes this module already ships. The file is written once off — it is never regenerated, so you are free to restructure it afterwards.
💡 When a component-library module such as Intent.Modules.Blazor.Components.MudBlazor is installed, this module stands down and the component library composes
MainLayout.razorwith its own components instead.
Prerendering
The Prerendering module setting controls whether the server renders each page's initial HTML before the interactive runtime takes over. It applies to all three render modes — Interactive Server, Interactive WebAssembly and Interactive Auto — and is off by default.
When it is off, App.razor emits the page's render mode with prerender: false:
protected IComponentRenderMode? GetRenderModeForPage()
{
return new InteractiveWebAssemblyRenderMode(prerender: false);
}
When it is on, the render mode is emitted with prerendering left at its framework default.
⚠️ Prerendering runs your pages on the server. Any data a page loads during prerender is therefore fetched by the server rather than by the browser, using whatever credentials the server has for that user — so a page that calls an authenticated API is making that call server-side. If you turn prerendering on for an application that uses Intent.Modules.Blazor.Authentication, make sure that module is up to date: it supplies the per-request server-side authorization handler that makes those calls safe.
AI Skill Samples
Each bundled AI skill (e.g. blazor-dialog-adding-entity) ships a SKILL.md and one or more sample files (e.g. add-entity-dialog-sample.razor) into your application's .agents/skills/<skill-name>/ folder. The sample files are regenerated on every Software Factory run until the skill's own SKILL.md has been hand-edited — once you customize a skill's instructions, its sample files are left untouched too, on the assumption you have taken over maintenance of the whole skill.
Securing Pages and UI Elements
The Secured stereotype can be used to secure specific UI elements or entire pages so that only users with the required policy or roles can access or view them.
The Secured stereotype can be applied to the following UI elements to restrict them for unauthorized users:
- Component
- Auto Complete
- Button
- CheckBox
- Link
- Menu Item
- Radio Group
- Select
- Table
- Text Input
This ensures that the element is not rendered if the user does not have the required permissions.
You can apply multiple Secured stereotypes to an element if multiple policies are required, or use a single Secured stereotype to specify multiple roles.
AuthenticationStateProvider Configuration
For authorization to work correctly, an AuthenticationStateProvider implementation must be registered with the DI container. Without this, your application’s navigation and authorization checks will not function properly.
The implementation you register should be based on your specific user authentication method. However, below are examples for development purposes, simulating a non-authenticated user and an always-authenticated user.
Non-Authenticated User
The following AuthenticationStateProvider implementation simulates an unauthorized user visiting the website.
Create this class in the .Client project (for example under Common/Auth/):
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
namespace Blazor.Sample.Client.Common.Auth;
public class NeverAuthenticatedAuthStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var user = new ClaimsPrincipal(new ClaimsIdentity());
return Task.FromResult(new AuthenticationState(user));
}
}
Then register it with DI. In Program.cs of the client project:
.
.
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddClientServices(builder.Configuration);
// IntentIgnore
builder.Services.AddScoped<AuthenticationStateProvider, NeverAuthenticatedAuthStateProvider>();
builder.Services.AddAuthorizationCore();
.
.
Always-Authenticated User
The following AuthenticationStateProvider implementation simulates an always-authorized user visiting the website.
Create this class in the .Client project (for example under Common/Auth/):
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
namespace Blazor.Sample.Client.Common.Auth;
public class AlwaysAuthenticatedAuthStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "Test User"),
new Claim(ClaimTypes.Email, "[email protected]"),
new Claim(ClaimTypes.Role, "Admin")
}, "FakeAuthentication");
var user = new ClaimsPrincipal(identity);
return Task.FromResult(new AuthenticationState(user));
}
}
Finally, register this provider in Program.cs of the client project.
💡 Only the
// IntentIgnorecomment and the line directly below it need to be added — all other lines will be generated automatically.
.
.
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddClientServices(builder.Configuration);
// IntentIgnore
builder.Services.AddScoped<AuthenticationStateProvider, AlwaysAuthenticatedAuthStateProvider>();
builder.Services.AddAuthorizationCore();
.
.