Type to search pages and rules.

Browse pages

Blazor Components

This page holds how the Blazor stack realizes the frontend component principles (Frontend components).

Markdown9 provisions

Intent#

This page holds how the Blazor stack realizes the frontend component principles (Frontend components). A client component renders what it is given and reports what the user did. Business rules stay in Domain and Application, browser access stays behind an interface, and each file holds one component.

Standards#

Keep components presentational#

ruleguidance

Requirement A component MUST NOT call a browser API, read persisted state directly, or contain a business rule.

Rationale A rule deciding whether an action is allowed belongs in Domain or Application, where a test can reach it without rendering.

litespec/frontend/blazor/components#keep-components-presentational

Declare every parameter type#

ruleguidance

Requirement A component parameter MUST declare a concrete type owned by its feature.

Rationale A loosely typed bag of values hides the contract, and a Domain aggregate crossing into a component couples rendering to the core model. This realizes litespec/frontend/components#keep-component-inputs-narrow.

litespec/frontend/blazor/components#declare-every-parameter-type

Raise events rather than mutating#

ruleguidance

Requirement A child component MUST report upward through EventCallback rather than mutate a parent-owned object.

Rationale Writing to a shared store to signal a parent hides the relationship that the callback makes visible.

litespec/frontend/blazor/components#raise-events-rather-than-mutating

Own the layer contract#

ruleguidance

Requirement A feature view model MUST expose no Domain aggregate, Domain closed set, or Application result record.

Rationale Each layer mirrors the shape it needs, as litespec/backend/architecture#own-each-layers-contract-types requires. Shared-kernel typed identifiers and value objects are the one sanctioned crossing.

This rule and litespec/frontend/blazor/structure#keep-domain-free-of-browser-concerns guard the same boundary from opposite sides. That rule keeps browser types out of Domain. This rule keeps Domain types out of the view. Neither implies the other, because a view model can name an aggregate without Domain naming a component.

litespec/frontend/blazor/components#own-the-layer-contract

Resolve browser behavior through an interface#

ruleguidance

Requirement A component MUST resolve browser behavior through an Application-owned interface rather than inject the interop runtime.

Rationale The component then renders in a test with no JavaScript host.

litespec/frontend/blazor/components#resolve-browser-behavior-through-an-interface

Place one component per file#

ruleguidance

Requirement A .razor file MUST declare one routable or reusable component named for what it renders.

Rationale Bundling components by kind hides each one. A component with more than trivial logic uses a code-behind partial class rather than a large inline block.

litespec/frontend/blazor/components#place-one-component-per-file

Keep accessibility in the component#

ruleguidance

Requirement A component MUST own focus management, keyboard interaction, labeling, and live-region announcements for its interaction.

Rationale A page that composes the component cannot know which element should receive focus. This realizes litespec/frontend/components#support-keyboard-focus-labels-and-announcements.

litespec/frontend/blazor/components#keep-accessibility-in-the-component

Conventions#

Name for the boundary role#

conventionguidance

Default Give a feature component a role suffix such as {UseCase}Form, {UseCase}Summary, {Concept}List, or {Concept}Card.

Replacement A consumer can replace this default with an explicit local convention.

Rationale A shared primitive is named for the primitive rather than the feature that first needed it. This realizes litespec/frontend/components#name-components-for-their-role.

litespec/frontend/blazor/components#name-for-the-boundary-role

Apply one styling system#

conventionguidance

Default Use one styling system with tokens defined once.

Replacement A consumer can replace this default with an explicit local convention.

Rationale A hard-coded color, spacing value, or font size duplicates a token that already exists. This realizes litespec/frontend/components#use-declared-visual-variants.

litespec/frontend/blazor/components#apply-one-styling-system

Verification#

IDMarkEvidence
litespec/frontend/blazor/components#keep-components-presentationalguidanceDoes any component resolve storage, interop, or a Domain service?
litespec/frontend/blazor/components#declare-every-parameter-typeguidanceDoes each parameter declare a feature-owned concrete type?
litespec/frontend/blazor/components#raise-events-rather-than-mutatingguidanceDoes each child report upward through a callback parameter?
litespec/frontend/blazor/components#own-the-layer-contractguidanceDoes any view model expose a Domain or Application type?
litespec/frontend/blazor/components#resolve-browser-behavior-through-an-interfaceguidanceDoes any component inject the interop runtime directly?
litespec/frontend/blazor/components#place-one-component-per-fileguidanceDoes each component file declare one primary component?
litespec/frontend/blazor/components#keep-accessibility-in-the-componentguidanceDo keyboard paths and announcements work in each interactive component?
litespec/frontend/blazor/components#name-for-the-boundary-roleguidanceDoes each feature component name match its rendered role?
litespec/frontend/blazor/components#apply-one-styling-systemguidanceIs each color, spacing, and font value a defined token?