Quick start

Minimal hello-world using RazorComponentEndpoints.


Quick start

Two-file app: a startup file and a page.

// Program.cs
using RazorComponentEndpoints;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponentEndpoints();

var app = builder.Build();
app.UseStaticFiles();
app.MapRazorComponentEndpoints();   // scans the calling assembly for @page components
app.Run();
@* Components/Pages/Index.razor *@
@page "/"
@layout PageShell

<h1>Hello, htmx!</h1>
<button hx-post="/api/click" hx-target="#out" hx-swap="innerHTML">Click me</button>
<div id="out"></div>
@* Components/Fragments/Click.razor — htmx posts here, gets back this markup *@
@page "/api/click"

<p>Clicked at @DateTime.Now.ToLongTimeString()</p>

Pages vs fragments

There's no distinction at the library level. The only difference is whether the component declares an @layout:

  • With @layout → wrapped in the layout (full HTML page suitable for the browser address bar).
  • Without @layout → renders bare (fragment suitable for an htmx swap).

Pick one or the other based on what the URL is for.

What you get out of the box

  • Route discovery via @page.
  • Parameter binding from route values, form body, and query string.
  • HttpContext and Task<AuthenticationState> supplied as root cascading values — <AuthorizeView> and [CascadingParameter] HttpContext work.
  • NavigationManager.NavigateTo(...) issues a 302 (or 204 + HX-Redirect for htmx-initiated requests).
  • [NotFoundPage] registers a component as the 404 fallback.

Details: see Authoring patterns.