useId
UtilitiesAccessible field IDs
Generate unique, hydration-stable IDs once and use them to connect labels to controls
bits-94bits-95Click either label to focus its control
unique IDs<script lang="ts">
import { useId } from 'bits-ui';
const projectId = useId();
const ownerId = useId();
let focusedId = $state<string | null>(null);
</script>
<div class="grid gap-4">
<div class="grid gap-2">
<div class="flex items-center justify-between gap-3">
<label class="text-sm font-medium text-ink-200" for={projectId}>Project name</label>
<code class="chip">{projectId}</code>
</div>
<input
class="input"
id={projectId}
placeholder="Design system refresh"
onfocus={() => (focusedId = projectId)}
onblur={() => (focusedId = null)}
/>
</div>
<div class="grid gap-2">
<div class="flex items-center justify-between gap-3">
<label class="text-sm font-medium text-ink-200" for={ownerId}>Owner email</label>
<code class="chip">{ownerId}</code>
</div>
<input
class="input"
id={ownerId}
type="email"
placeholder="team@example.com"
onfocus={() => (focusedId = ownerId)}
onblur={() => (focusedId = null)}
/>
</div>
<div class="panel flex flex-wrap items-center justify-between gap-3 p-3 text-sm">
<p class="text-ink-200">
{focusedId ? `Label/control pair active: ${focusedId}` : 'Click either label to focus its control'}
</p>
<span class="chip">{projectId === ownerId ? 'collision' : 'unique IDs'}</span>
</div>
</div>
Call useId() during component initialization, not in an event handler or a changing loop. The returned value can connect label[for] to a control's id, or wire ARIA relationships without requiring a caller-supplied identifier.
Bits UI uses the same generator internally for component relationships. Keeping the call order stable between server rendering and hydration keeps those IDs aligned; each call in one component instance returns a distinct value.