ASP.NET Core
Home-UI is server-rendered HTML plus two static files, so it drops into ASP.NET Core with no client build: a Razor layout loads the pair, a view writes the elements, and model binding reads their values on POST.
Load the two files
Section titled “Load the two files”In Views/Shared/_Layout.cshtml, or the layout a Razor Page uses:
<!doctype html><html lang="en" class="@(Model.Theme ?? "light")"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="https://home-ui.harriverse.com/dist/latest/home-ui.css" /> <script type="module" src="https://home-ui.harriverse.com/dist/latest/home-ui.js"></script> </head> <body class="hui-surface"> @RenderBody() </body></html>Theme is "light" or "dark", read from the request server-side, so there is no flash of the
wrong theme. hui-surface opts the page into the tokens; see Dark mode.
Those URLs load the current build from this site. For something you ship, download the files and serve them yourself - see Getting the files.
Components are attributes
Section titled “Components are attributes”A component is configured entirely by attributes, so Razor writes them like any other tag:
<hui-field> <span data-label>Project name</span> <hui-input data-control name="Project" value="@Model.Form.Project" aria-invalid="@(Model.Errors.ContainsKey("Project") ? "true" : null)"></hui-input> @if (Model.Errors.TryGetValue("Project", out var error)) { <span data-error>@error</span> }</hui-field>Razor omits an attribute whose value is null, so aria-invalid appears only when the field is
invalid. hui-field wires the label and the error to the control for you.
Reading values on POST
Section titled “Reading values on POST”Every form-associated control submits under its name, so ordinary model binding picks the values
up with nothing special:
public class ProjectForm{ public string? Project { get; set; } public string? Volume { get; set; }}
[BindProperty]public ProjectForm Form { get; set; } = new();
public IActionResult OnPost(){ if (!ModelState.IsValid) return Page(); // re-render with the errors
Save(Form); return RedirectToPage("./Index");}Volume, from hui-slider, arrives as a string exactly as a native field would.
Validation errors
Section titled “Validation errors”Business validation is the server’s. On a failed POST, re-render the same view with the submitted
values and an error per field; the template above then marks the control aria-invalid and wires
the message to it. The client does not reconstruct that.
<form method="post"> @Html.AntiForgeryToken() <!-- hui-field, hui-input and the rest --> <hui-button type="submit">Save</hui-button></form>hui-button type="submit" drives the ancestor form, so it can replace <button type="submit">
wherever you want the component’s styling.
Partial updates
Section titled “Partial updates”To update part of the page, return a partial from an action and swap it in. Any technique works -
fetch, HTMX, or Blazor’s interop; the element is created from the new
markup and re-associates with its form. Keep endpoints, tokens and record ids on the server: there
is no attribute for them, deliberately.