PHP
Home-UI is server-rendered HTML plus two static files, so it fits Laravel or plain PHP with no client build: a layout loads the pair, the template writes the elements, and the request handler reads their values.
Load the two files
Section titled “Load the two files”A Laravel Blade layout:
<!doctype html><html lang="en" class="{{ $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"> @yield('content') </body></html>Plain PHP is the same idea with <?= $theme ?>. class="light" or class="dark" is read
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 Blade or PHP writes them like any other tag:
<hui-field> <span data-label>Project name</span> <hui-input data-control name="project" value="{{ old('project', $project->name) }}" @error('project') aria-invalid="true" @enderror></hui-input> @error('project')<span data-error>{{ $message }}</span>@enderror</hui-field>old('project', ...) re-fills the field after a failed POST; the @error directive marks it
invalid and supplies the message that hui-field wires to the control.
Reading values on POST
Section titled “Reading values on POST”Every form-associated control submits under its name, so the handler reads it like any native
field:
// Laravel$project = $request->input('project');$volume = $request->input('volume'); // from hui-slider, a string// Plain PHP$project = $_POST['project'];$volume = $_POST['volume'];Validation errors
Section titled “Validation errors”Business validation is the server’s. On a failed POST, re-render the form with the submitted values
and an error per field; the template above marks the control aria-invalid and wires the message
to it. The client does not reconstruct that.
<form method="post"> @csrf <!-- 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, render a partial and swap it in. Any technique works - fetch,
HTMX, or Livewire’s own diffing; 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. The full model is in
server-side mechanics.