Skip to content
HHydro UIdocs
Navigate
DocumentationGuidesForms and SSR
GuideHydro UI

Forms and SSR

Keep native values, relationships, and server markup intact.

Hydro UI keeps form values close to the browser. Native-first controls render real inputs where possible; composite controls mirror their committed values to visually hidden native inputs.

Field relationships

<hui-field id="email-field" invalid>
  <hui-field-label>Email</hui-field-label>
  <input name="email" type="email" />
  <hui-field-description>Use your work address.</hui-field-description>
  <hui-field-error>Enter a valid email address.</hui-field-error>
</hui-field>

Give fields stable IDs when generated label, description, and error relationships are useful. The field does not own the projected control's value, disabled state, or native constraint validation.

Source of truth

checkbox.toggleAttribute("checked");
select.setAttribute("value", "standard");
dialog.removeAttribute("open");

Do not mutate derived data-state attributes directly. They are mirrors for styling and inspection.

Server rendering

Server-rendered markup includes critical state such as checked, value, ARIA relationships, and hidden. Load the server DOM integration before importing Hydro UI, then register components inside the isolated withServerDOM session.

import { withServerDOM } from "hydro-js-integrations/server";

const html = await withServerDOM({}, async ({ document }) => {
  const { registerAll } = await import("hydro-ui");
  registerAll();
  const holder = document.createElement("div");
  holder.innerHTML = `<hui-checkbox checked>Ready</hui-checkbox>`;
  document.body.append(...holder.childNodes);
  return document.documentElement.outerHTML;
});

Closed overlays remain hidden on the server. Client enhancement adds focus management, positioning, portals, and dismissal without changing the public light-DOM contract.