
State in url
State management and URL sync
Sync any JavaScript state to URL query parameters — objects, arrays, and dates. Fully typed, shareable, and persistent across reloads.
useUrlState — demo with next.js
Try to type something
Reads from URL — no props, no context, types and structure are preserved
{name: stringage: undefinedundefinedagree_to_terms: falsebooleantags: []}
Instructions for:
Quick start
export const form: Form = {
name: '',
age: undefined,
agree_to_terms: false,
tags: [],
};
// use `Type` not `Interface`!
type Form = {
name: string;
age?: number;
agree_to_terms: boolean;
tags: { id: string; value: { text: string; time: Date } }[];
};'use client';
import { useUrlState } from 'state-in-url/next';
import { form } from './form';
export const ComponentA = () => {
// see docs for all possible params https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/next/useUrlState
// useHistory: false to update sp on server component
const { urlState, setState, setUrl } = useUrlState(form, { useHistory: true });
return <>
<input
id="name"
value={urlState.name}
onChange={(ev) => setUrl({ name: ev.target.value })}
/>
// OR can update state immediately but sync change to url as needed
<input
value={urlState.name}
onChange={(ev) => { setState(curr => ({ ...curr, name: ev.target.value })) }}
onBlur={() => setUrl()}
/>
<button onClick={() => setUrl((curr, initial) => initial)}>
Reset
</button>
</>
};'use client';
import { useUrlState } from 'state-in-url/next';
import { form } from './form';
// "searchParams" used to pass params from Server Components
export const ComponentB = ({ searchParams }: { searchParams?: object }) => {
const { urlState } = useUrlState(form, { searchParams });
// will be defaultValue from `form` if not in url, no need to check
return <div>name: {urlState.name}</div>
};'use client';
import React from 'react';
import { useUrlState } from 'state-in-url/next';
const form: Form={
name: '',
age: undefined,
agree_to_terms: false,
tags: [],
};
type Form = {
name: string;
age?: number;
agree_to_terms: boolean;
tags: {id: string; value: {text: string; time: Date } }[];
};
export const useFormState = ({ searchParams }: { searchParams?: object }) => {
const { urlState, setUrl: setUrlBase, reset } = useUrlState(form, {
searchParams,
});
// first navigation will push new history entry
// all following will just replace that entry
// this way will have history with only 2 entries - ['/url', '/url?key=param']
const replace = React.useRef(false);
const setUrl = React.useCallback((
state: Parameters<typeof setUrlBase>[0],
opts?: Parameters<typeof setUrlBase>[1]
) => {
setUrlBase(state, { replace: replace.current, ...opts });
replace.current = true;
}, [setUrlBase]);
return { urlState, setUrl, resetUrl: reset };
};Why state-in-url?
URL state libraries exist, but most are either too cumbersome to set up or too limited in what they can store. state-in-url aims to be the one that just works.
state-in-url provides the useUrlState hook for Next.js and react-router. Store state without boilerplate, implement deep links, and share data between unrelated client components — no provider needed. API mirrors React.useState.
Structure and types are preserved, with full TypeScript support.
Code quality
Built with best practices and TDD — production-ready.
Other frameworks or pure JS
More hooks and helpers for serialization and decoding of data.
Check out the GitHub page — a star goes a long way.
Share with other devs
