Skip to content

useUrlState

Synchronizes state with the URL query string via History API.

Synchronizes state with the URL query string via History API.

Import

import { useUrlState } from '@kamod-ch/hooks'

Live demo

Basic demo

Synchronizes state with the URL query string via History API.

Browser-only demo

This demo starts after the page mounts in the browser.
import { useEffect, useRef } from 'preact/hooks'
import { useUrlState } from '@kamod-ch/hooks'

export default function UseUrlStateDemo() {
  const original = useRef('')
  useEffect(() => {
    original.current = window.location.search
  }, [])

  const [state, setState] = useUrlState({ khDemoView: 'cards', khDemoFilter: 'all' }, { navigateMode: 'replace' })

  return (
    <div>
      <p><strong>Query state:</strong> {JSON.stringify(state)}</p>
      <p><strong>Current search:</strong> {window.location.search || '(empty)'}</p>
      <div class="demo-actions">
        <button type="button" onClick={() => setState((current) => ({ ...current, khDemoView: current.khDemoView === 'cards' ? 'table' : 'cards' }))}>Toggle view</button>
        <button type="button" onClick={() => setState({ khDemoView: 'cards', khDemoFilter: 'all' })}>Reset params</button>
        <button type="button" onClick={() => window.history.replaceState(window.history.state, '', window.location.pathname + original.current + window.location.hash)}>Restore original URL</button>
      </div>
    </div>
  )
}

API

TypeScript signature
import type { SetStateAction } from "../utils/types-compat.js";
export interface UrlStateOptions {
    navigateMode?: "push" | "replace";
}
type UrlState = Record<string, string | string[] | undefined>;
declare const useUrlState: <S extends UrlState = UrlState>(baseState?: S | (() => S), options?: UrlStateOptions) => readonly [{ [key in keyof S]: Required<S>[key] extends unknown[] ? string[] : string; }, (this: unknown, s: SetStateAction<{ [key in keyof S]: Required<S>[key] extends unknown[] ? string[] : string; }>) => void];
export default useUrlState;
/

SSR considerations

This hook touches browser APIs. Render it after mount or guard it with BrowserOnly in SSR and static builds.

Browser compatibility

Requires the corresponding browser API to exist in the current environment.

Related hooks