URL State Hooks
Build custom components that sync state to the URL using the same hooks as Cubitt.
Use these hooks when you're building custom components and want them to behave exactly like Cubitt's built-in URL state props.
Many Cubitt components already support URL state out of the box. Start with the URL state guide if you're using the built-in components.
Hooks
useUrlOpen
Read-only open/close state for dialogs, sheets, alert dialogs, and popovers.
useUrlTrigger
Write-only URL updates for buttons, menu items, and other triggers.
useUrlState
Two-way sync for inputs, toggles, tabs, pagination, and other value controls.
useUrlControlledString
Controlled string inputs that mirror URL state without losing local control.
Router setup
These hooks must run inside TanStack Router context.
- TanStack Start / file-based routing usually generates the router registration for you.
- Manual TanStack Router setup should still use the standard
Registerdeclaration once soparamNamenarrows to known search keys.
With registration in place, the hook layer can:
- autocomplete valid
paramNamekeys - reject invalid keys at compile time
- keep URL-state usages aligned when route search keys change
If your app only sees paramName as plain string, verify that your router registration is present and that the generated route types are up to date.
Building your own components
The hooks are designed to align with shared prop types so your components stay consistent with Cubitt:
import type {
UrlOpenComponentProps,
UrlTriggerComponentProps,
UrlStateComponentProps,
} from "@tilt-legal/cubitt-components/utilities/hooks";Pick the hook that matches your component's behavior and pass through the URL props.
Validation model
Cubitt URL-state hooks intentionally split responsibilities:
- Cubitt codecs parse and serialize the single URL param the hook owns.
- Your route
validateSearchowns full-object validation, transforms, and defaults.
That keeps the hooks route-agnostic while still allowing strong typing and app-level search validation.
Codecs
Custom codecs for use with paramCodec on any URL-state hook.
import {
booleanOrIndeterminateCodec,
createJsonCodec,
} from "@tilt-legal/cubitt-components/utilities/hooks";booleanOrIndeterminateCodec
Parses a URL param as boolean | "indeterminate". Useful for checkbox tri-state values that need more than the default boolean codec.
<Checkbox paramName="agree" paramCodec={booleanOrIndeterminateCodec} />createJsonCodec
Builds a JSON codec with a validator function. Use this for complex objects or arrays in URL params.
const myCodec = createJsonCodec<MyFilter>((value) =>
isValidFilter(value) ? value : null
);If your app uses a custom TanStack Router serializer that leaves complex values as raw strings, opt in explicitly with parseRawString so the codec can deserialize those strings before validation:
const myCodec = createJsonCodec<MyFilter>(
(value) => (isValidFilter(value) ? value : null),
{
parseRawString: customParseSearchValue,
}
);