Write Blazor UI as plain C#

An ordinary Blazor component, written in the language the rest of the app is written in.

dotnet add package BlazorCodeFirst --prerelease
Get started

The expression names the HTML it produces

Attributes chain onto the element, children go in brackets, and a bare string is a text node.

What you writeC#
protected override View Body =>
    Section.Class("prose")[
        H1["Blazor UI in C#"],
        P["Attributes first."],
        A.Href("/docs")["The guide"]];
What it rendersHTML
<section class="prose">
    <h1>Blazor UI in C#</h1>
    <p>Attributes first.</p>
    <a href="/docs">The guide</a>
</section>

Some HTML that parses is still wrong

A void element with children prerenders one DOM tree and hydrates another, so the build refuses it by name.

dotnet builderror
Pages/Broken.cs(14,13): error BCF3016:
'img' is a void element and cannot have
children; prerendering pushes them out of the
element while interactive rendering keeps them
inside, so the two disagree. Remove the children,
or place them beside the element.

The expression does not survive the build

The generator translates it into a RenderView override on the same partial class, and the IL trimmer removes the design-time API it was written with. Adjacent constants fold, so the class channel below costs one attribute frame.

What you writedesign time
Button
    .Class("btn")
    .Class("btn-primary")
    .OnClick(() => Save())["Save"]
What it compiles togenerated
// Both .Class calls fold into one attribute frame.
__builder.OpenElement(0, "button");
__builder.AddAttribute(1, "class", "btn btn-primary");
__builder.AddAttribute(2, "onclick", /* () => Save() */);
__builder.AddContent(3, "Save");
__builder.CloseElement();

Read the guide

The surface is small enough to read end to end.

An unhandled error has occurred. Reload 🗙