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

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 Register declaration once so paramName narrows to known search keys.

With registration in place, the hook layer can:

  • autocomplete valid paramName keys
  • 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 validateSearch owns 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,
  }
);

On this page