Working with HTMX and Razor Components
By FoxLearn 2/7/2025 8:18:32 AM 92
Similar to how JSX is used in React, Razor components combine HTML with C# code to produce dynamic and interactive web pages. With the introduction of the RazorComponentResult
type in .NET 8, we now have a powerful tool to enhance our HTMX development.
In our previous guide, Introduction to HTMX with .NET, we worked with the HtmlContentBuilder
class to generate HTML dynamically. With the RazorComponentResult
class, we can now take full advantage of Razor components while working seamlessly with HTMX.
Let's walk through a practical example where we integrate Razor components to display and manage a product catalog.
Step 1: ProductComponent.razor
First, let's create the ProductComponent.razor
file to render a single product in the catalog:
<div> <h3>@Model.Name</h3> <p>@Model.Description</p> <p>@Model.Price</p> <button hx-delete="/products/@Model.Id" hx-target="closest div" hx-swap="outerHTML">Remove</button> </div> @code { [Parameter] public ProductModel Model { get; set; } = new(); }
In this file, we render the product's name, description, and price, along with a button to remove the product from the list. The hx-delete
attribute will trigger an HTMX call to delete the product.
Step 2: ProductFormComponent.razor
Next, we create a form to allow the user to add a new product to the catalog:
<form hx-post="/products" hx-swap="beforebegin" hx-ext="json-enc"> <input type="text" name="name" placeholder="Product Name" /> <input type="text" name="description" placeholder="Product Description" /> <input type="number" name="price" placeholder="Price" /> <button type="submit">Add Product</button> </form> @code { }
Step 3: ProductListComponent.razor
Now, we will create the ProductListComponent.razor
to loop through all products and display them using the ProductComponent
:
<div> @foreach (var product in Model) { <ProductComponent Model="@product"></ProductComponent> } <ProductFormComponent></ProductFormComponent> </div> @code { [Parameter] public List<ProductModel> Model { get; set; } = new(); }
Step 4: DocumentComponent.razor
The root component that ties everything together will be the DocumentComponent.razor
file:
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://unpkg.com/[email protected]" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script> <script src="https://unpkg.com/htmx.org/dist/ext/json-enc.js"></script> </head> <body hx-get="/products" hx-trigger="load" hx-swap="innerHTML"> </body> </html> @code { }
Step 5: Program.cs Configuration
Finally, we configure the routes in Program.cs
to make the application functional:
using Microsoft.AspNetCore.Http.HttpResults; using ProductApi; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents(); var app = builder.Build(); var db = new List<ProductModel>() { new ProductModel() { Id = Guid.NewGuid(), Name = "Laptop", Description = "High-performance laptop", Price = 1200.00M }, new ProductModel() { Id = Guid.NewGuid(), Name = "Smartphone", Description = "Latest smartphone", Price = 800.00M }, }; app.MapGet("/", () => new RazorComponentResult<DocumentComponent>()); app.MapGet("/products", () => new RazorComponentResult<ProductListComponent>(new { Model = db })); app.MapPost("/products", (AddProductCommand command) => { var product = new ProductModel { Id = Guid.NewGuid(), Name = command.Name, Description = command.Description, Price = command.Price }; db.Add(product); return new RazorComponentResult<ProductComponent>(new { Model = product }); }); app.MapDelete("/products/{id}", (string id) => { var product = db.First(p => p.Id.ToString() == id); db.Remove(product); }); app.Run();
By utilizing Razor components in .NET 8, we can simplify the structure of our web application and create reusable components that encapsulate both logic and HTML. The combination of Razor components and HTMX gives us the flexibility and power needed to build interactive web applications efficiently.