Conveniently render strongly-typed Razor Components and Fragments via Minimal APIs
Add NuGet
> dotnet add package BlazorBladesAdd these to your Component.razor
- Add
@inherits BlazorBlade<Model> - Add
@implements IMapEndpoints - Implement
MapEndpoints()in@code{ }orComponent.razor.cs
// MyComponent.razor
@inherits BlazorBlade<Model> // Generates @Model, Blade(), RenderAsync()
@implements IMapEndpoints // Provides MapEndpoints()
// Generated @Model Property
<div>Hello @Model.Name !</div>
@code
{
public static void MapEndpoints(IEndpointRouteBuilder app)
{
app.MapGet("/component", () =>
{
var model = new Model("Jason");
// Strongly-Typed RazorComponentResult
return MyComponent.Blade(model);
});
app.MapGet("/fragment", async () =>
{
var message = "Developers, Developers, Developers!"
// Inline Fragment Result
return Results.Razor
(
@<div>
Quote: @message
</div>
);
});
app.MapGet("/raw", (IServiceProvider services) =>
{
// Render Component
var html = await MyComponent.RenderAsync(services, new Model("Jason"));
// Render Fragment
var html = await HelperFragments.SayHello("Julia").RenderAsync()
...
});
}
}Add app.MapEndpoints() to program.cs to map all IMapEndpoints components
var app = builder.Build();
...
app.MapEndpoints();
...The sample web app in Components/Page.razor has several examples.
Blazor Blades is an experimental project inspired by RazorSlices, but built around Blazor .razor components instead of Razor .cshtml templates. It's aimed at devs looking for a .NET hypermedia workflow that is strongly typed end-to-end while keeping the benefits of Blazor components.
I wanted a way to build HTML-first applications using Minimal APIs with:
- Compile-time type safety for the data each rendered template requires
- Template composition and reuse through components and functions
- Locality of template, model, and endpoint code
- Any Javascript library for interactivity (Datastar, Htmx, jQuery, etc.)
BlazorBlades lets a .razor component opt into generated capabilities:
@inherits BlazorBlade<TModel>provides a StaticComponent.Blade(model)@implements IMapEndpointsprovides a StaticComponent.RenderAsync(services, model)app.MapEndpoints()automatically callsComponent.MapEndpoints(app)
Two component marker interfaces and source generators are used to accomplish this:
BlazorBlades also makes working with RenderFragement easier with:
Results.Razor(fragment)fragment.RenderAsync(services)fragment.Blade()
I'm Jason Barnes - Follow me: @vyrotek