useCapxulUsernameAvailability
Debounced query hook that checks whether the username the user is typing is available, returning the canonical stored form.
Checks whether a username is available while the user is typing it —
usually next to the username field of
useCapxulAuth.
The candidate is debounced (300 ms by default) and the query stays
disabled until it reaches the 3-character floor, so keystrokes do not fan out
into requests.
Import
import { useCapxulUsernameAvailability } from "@capxul/sdk-react";Usage
"use client";
import { useCapxulUsernameAvailability } from "@capxul/sdk-react";
function UsernameField({ value, onChange }: { value: string; onChange: (v: string) => void }) {
const availability = useCapxulUsernameAvailability(value);
return (
<label>
Username
<input value={value} onChange={(event) => onChange(event.target.value)} />
{availability.isFetching && <span>Checking…</span>}
{availability.error && <span>{availability.error.message}</span>}
{availability.data &&
(availability.data.available ? (
<span>{availability.data.normalized} is available</span>
) : (
<span>{availability.data.normalized} is taken</span>
))}
</label>
);
}Usernames are stored normalized: trimmed, lowercased, 3–30 characters of
a-z, 0-9, or underscore. normalized echoes that canonical form so the UI
can show exactly what would be stored. A username the signed-in user already
owns counts as available (re-submitting onboarding is idempotent).
Parameters
| Parameter | Type | Description |
|---|---|---|
username | string | The candidate the user is typing. Trimmed before debouncing. |
options.enabled | boolean | Optional extra gate on top of the built-in ones. Default true. |
options.debounceMs | number | Optional debounce window for the candidate. Default 300. |
The query is additionally gated on the provider bootstrap and on the debounced candidate reaching 3 characters.
Return type
import { type UseCapxulUsernameAvailabilityReturn } from "@capxul/sdk-react";
// UseQueryResult<UsernameAvailability, CapxulError>data is a UsernameAvailability:
| Field | Type | Description |
|---|---|---|
available | boolean | Whether no one else owns the normalized username. |
normalized | string | The canonical stored form of the candidate. |
The hook returns TanStack Query's UseQueryResult. The most-used fields:
| Field | Description |
|---|---|
data | The query data (typed per hook, shown above). undefined until the first success. |
error | A CapxulError when the last fetch failed, otherwise null. |
status | 'pending' | 'error' | 'success'. |
isLoading | true during the first fetch (no data yet). |
isFetching | true whenever a fetch is in flight, including background refetches. |
refetch | Manually refetch the query. |
Capxul query hooks stay pending until the provider finishes bootstrapping —
you do not need to gate them on useCapxul() yourself. The full field list is
in the TanStack Query useQuery reference;
see also the TanStack Query integration guide.
Query key
["capxul", "profile", "username-availability", <candidate>] — keyed by the
debounced candidate, so each probed username caches independently under the
authenticated capxul root.
Errors
A malformed or reserved candidate surfaces as a
CapxulError on error — INVALID_INPUT with
the boundary's message (for example "must be 3-30 characters of a-z, 0-9, or
underscore" or "username is reserved") — not as available: false. Only a
username someone else owns reads as taken.
Client method
This hook wraps client.identity.usernameAvailable(username)
on the core SDK.