パッケージの詳細

state-in-url

asmyshlyaev17775.1kMIT5.1.0

Store state in URL as in object, types and structure are preserved, with TS validation. Same API as React.useState, wthout any hasssle or boilerplate. Next.js@14-15, react-router@6-7, and remix@2.

state in url, useSearchParams, useUrlState, url state

readme

English | 한국어 | 简体中文

state-in-url logo # State in url
npm npm bundle size (minified + gzip) Codacy Badge Tests Codacy Badge Commitizen friendly semantic-release: angular) OpenSSF Scorecard OpenSSF Best Practices license

Don't hesitate to open an issue if you found a bug, or for requesting features

Demo-gif # Demo Demo | Mirror link URI size limitation, up to 12KB is safe
Add a and follow me to support the project! Will appreciate you feedback/opinion on discussions Share if it useful for you. X.com LinkedIn FB VK

Just Show Me Code!

Why use state-in-url?

Store any user state in query parameters; imagine JSON in a browser URL. All of it with keeping types and structure of data, e.g. numbers will be decoded as numbers not strings, dates as dates, etc, objects and arrays supported. Dead simple, fast, and with static Typescript validation. Deep links, aka URL synchronization, made easy.

Contains useUrlState hook for Next.js and react-router, and helpers for anything else on JS. Since modern browsers support huge URLs and users don't care about query strings (it is a select all and copy/past workflow).

Time to use query string for state management, as it was originally intended. This library does all mundane stuff for you.

This library is a good alternative for NUQS.

Use cases

  • Store unsaved user forms or page filters in URL
  • Sycn URL with React state
  • Just sync data between unrelated client components without touching URI
  • Shareable URLs with application state (Deep linking, URL state synchronization)
  • Easy state persistence across page reloads

Features

  • 🧩 Simple: No providers, reducers, boilerplate or new concepts, API similar to React.useState
  • 📘 Typescript validation/autocomplete: State is just an object, automatic static validation in IDE/tests according to Typescript definition
  • Complex data: Nested objects, dates and arrays, works same as JSON, but in URL
  • Default values: Giving you default values if parameter not in url
  • Organized: All possible values defined at start, protect you from getting non existing key
  • compatible: Will keep 3rd party query params as is
  • flexible: Can use more than 1 state objects on the same page, just use different keys
  • Fast: Minimal rerenders, around 1ms to encode and decode big object
  • Server Side Rendering: Can use it in Server Components, Next.js 14 and 15 are supported
  • Lightweight: Zero dependencies, library less than 2KB
  • DX: Good developer experience, documentation, JSDoc comments, and examples
  • Framework Flexibility: Hooks for Next.js and react-router, helpers to use it with other frameworks or pure JS
  • Well tested: Unit tests and Playwright tests for Chrome/Firefox/Safari
  • Permissive license: MIT

Table of content

installation

1. Install package

# npm
npm install --save state-in-url
# yarn
yarn add state-in-url
# pnpm
pnpm add state-in-url

2. Edit tsconfig.json

In tsconfig.json in compilerOptions set "moduleResolution": "Bundler", or"moduleResolution": "Node16", or "moduleResolution": "NodeNext". Possibly need to set "module": "ES2022", or "module": "ESNext"

useUrlState

Main hook that takes initial state as parameter and returns state object, callback to update url, and callback to update only state. All components that use the same state object are automatically synchronized.

useUrlState hook for Next.js

Full API Docs

React-Router example

Usage examples

Basic
  1. Define state shape with default values

    // userState.ts
    // Only parameters with value different from default will go to the url.
    export const userState: UserState = { name: '', age: 0 }
    
    // use `Type` not `Interface`!
    type UserState = { name: string, age: number }
  2. Import it and use

'use client'
import { useUrlState } from 'state-in-url/next';

import { userState } from './userState';

function MyComponent() {
  // can pass `replace` arg, it's control will `setUrl` will use `rounter.push` or `router.replace`, default replace=true
  // can pass `searchParams` from server components, pass `useHistory: false` if you need to fetch smt in the server component
  const { urlState, setUrl, setState, reset } = useUrlState(userState);

  return (
    <div>
      // urlState.name will return default value from `userState` if url empty
      <input value={urlState.name}
        // same api as React.useState, e.g. setUrl(currVal => currVal + 1)
        onChange={(ev) => setUrl({ name: ev.target.value }) }
      />
      <input value={urlState.age}
        onChange={(ev) => setUrl({ age: +ev.target.value }) }
      />

      <input value={urlState.name}
        onChange={(ev) => { setState(curr => ({ ...curr, name: ev.target.value })) }}
        // Can update state immediately but sync change to url as needed
        onBlur={() => setUrl()}
      />

      <button onClick={reset}>
        Reset
      </button>

    </div>
  )
}
Custom hook to work with slice of state conveniently
<Summary>Example</Summary> typescript '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 }; };

With complex state shape
<Summary>Example</Summary> typescript export 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 } }[]; }; typescript 'use client' import { useUrlState } from 'state-in-url/next'; import { form } from './form'; function TagsComponent() { // `urlState` will infer from Form type! const { urlState, setUrl } = useUrlState(form); const onChangeTags = React.useCallback( (tag: (typeof tags)[number]) => { setUrl((curr) => ({ ...curr, tags: curr.tags.find((t) => t.id === tag.id) ? curr.tags.filter((t) => t.id !== tag.id) : curr.tags.concat(tag), })); }, [setUrl], ); return ( <div> <Field text="Tags"> <div className="flex flex-wrap gap-2"> {tags.map((tag) => ( <Tag active={!!urlState.tags.find((t) => t.id === tag.id)} text={tag.value.text} onClick={() => onChangeTags(tag)} key={tag.id} /> ))} </div> </Field> </div> ); } const tags = [ { id: '1', value: { text: 'React.js', time: new Date('2024-07-17T04:53:17.000Z') }, }, { id: '2', value: { text: 'Next.js', time: new Date('2024-07-18T04:53:17.000Z') }, }, { id: '3', value: { text: 'TailwindCSS', time: new Date('2024-07-19T04:53:17.000Z') }, }, ]; Demo page example code
Update state only and sync to URL manually
<Summary>Example</Summary> typescript const timer = React.useRef(0 as unknown as NodeJS.Timeout); React.useEffect(() => { clearTimeout(timer.current); timer.current = setTimeout(() => { // will compare state by content not by reference and fire update only for new values setUrl(urlState); }, 500); return () => { clearTimeout(timer.current); }; }, [urlState, setUrl]); Syncing state onBlur will be more aligned with real world usage. typescript <input onBlur={() => updateUrl()} .../>
With server side rendering
<Summary>Example</Summary> typescript export default async function Home({ searchParams }: { searchParams: object }) { return ( <Form searchParams={searchParams} /> ) } // Form.tsx 'use client' import React from 'react'; import { useUrlState } from 'state-in-url/next'; import { form } from './form'; const Form = ({ searchParams }: { searchParams: object }) => { const { urlState, setState, setUrl } = useUrlState(form, { searchParams }); }
Using hook in layout component
<Summary>Example</Summary> That a tricky part, since nextjs with app router doesn't allow to access searchParams from server side. There is workaround with using middleware, but it isn't pretty and can stop working after nextjs update. typescript // add to appropriate `layout.tsc` export const runtime = 'edge'; // middleware.ts import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; export function middleware(request: NextRequest) { const url = request.url?.includes('_next') ? null : request.url; const sp = url?.split?.('?')?.[1] || ''; const response = NextResponse.next(); if (url !== null) { response.headers.set('searchParams', sp); } return response; } // Target layout component import { headers } from 'next/headers'; import { decodeState } from 'state-in-url/encodeState'; export default async function Layout({ children, }: { children: React.ReactNode; }) { const sp = headers().get('searchParams') || ''; return ( <div> <Comp1 searchParams={decodeState(sp, stateShape)} /> {children} </div> ); }
With arbitrary state shape (not recommended)
<Summary>Example</Summary> typescript 'use client' import { useUrlState } from 'state-in-url/next'; const someObj = {}; function SettingsComponent() { const { urlState, setUrl, setState } = useUrlState<object>(someObj); }

useUrlState hook for Remix.js

API is same as for Next.js version, except can pass options from NavigateOptions type.

API Docs

Example

export 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 } }[];
};
import { useUrlState } from 'state-in-url/remix';

import { form } from './form';

function TagsComponent() {
  const { urlState, setUrl, setState } = useUrlState(form);

  const onChangeTags = React.useCallback(
    (tag: (typeof tags)[number]) => {
      setUrl((curr) => ({
        ...curr,
        tags: curr.tags.find((t) => t.id === tag.id)
          ? curr.tags.filter((t) => t.id !== tag.id)
          : curr.tags.concat(tag),
      }));
    },
    [setUrl],
  );

  return (
    <div>
      <Field text="Tags">
        <div className="flex flex-wrap gap-2">
          {tags.map((tag) => (
            <Tag
              active={!!urlState.tags.find((t) => t.id === tag.id)}
              text={tag.value.text}
              onClick={() => onChangeTags(tag)}
              key={tag.id}
            />
          ))}
        </div>
      </Field>

      <input value={urlState.name}
        onChange={(ev) => { setState(curr => ({ ...curr, name: ev.target.value })) }}
        // Can update state immediately but sync change to url as needed
        onBlur={() => setUrl()}
      />
    </div>
  );
}

const tags = [
  {
    id: '1',
    value: { text: 'React.js', time: new Date('2024-07-17T04:53:17.000Z') },
  },
  {
    id: '2',
    value: { text: 'Next.js', time: new Date('2024-07-18T04:53:17.000Z') },
  },
  {
    id: '3',
    value: { text: 'TailwindCSS', time: new Date('2024-07-19T04:53:17.000Z') },
  },
];

Example code

useUrlState hook for React-Router

API is same as for Next.js version, except can pass options from NavigateOptions type.

API Docs

Example

export 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 } }[];
};
import { useUrlState } from 'state-in-url/react-router';

import { form } from './form';

function TagsComponent() {
  const { urlState, setUrl, setState } = useUrlState(form);

  const onChangeTags = React.useCallback(
    (tag: (typeof tags)[number]) => {
      setUrl((curr) => ({
        ...curr,
        tags: curr.tags.find((t) => t.id === tag.id)
          ? curr.tags.filter((t) => t.id !== tag.id)
          : curr.tags.concat(tag),
      }));
    },
    [setUrl],
  );

  return (
    <div>
      <Field text="Tags">
        <div className="flex flex-wrap gap-2">
          {tags.map((tag) => (
            <Tag
              active={!!urlState.tags.find((t) => t.id === tag.id)}
              text={tag.value.text}
              onClick={() => onChangeTags(tag)}
              key={tag.id}
            />
          ))}
        </div>
      </Field>

      <input value={urlState.name}
        onChange={(ev) => { setState(curr => ({ ...curr, name: ev.target.value })) }}
        // Can update state immediately but sync change to url as needed
        onBlur={() => setUrl()}
      />
    </div>
  );
}

const tags = [
  {
    id: '1',
    value: { text: 'React.js', time: new Date('2024-07-17T04:53:17.000Z') },
  },
  {
    id: '2',
    value: { text: 'Next.js', time: new Date('2024-07-18T04:53:17.000Z') },
  },
  {
    id: '3',
    value: { text: 'TailwindCSS', time: new Date('2024-07-19T04:53:17.000Z') },
  },
];

Example code

Other hooks and helpers

useUrlStateBase hook for others routers

Hooks to create your own useUrlState hooks with other routers, e.g. react-router or tanstack router.

API Docs

useSharedState hook for React.js

Hook to share state between any React components, tested with Next.js and Vite.

'use client'
import { useSharedState } from 'state-in-url';

export const someState = { name: '' };

function SettingsComponent() {
  const { state, setState } = useSharedState(someState);
}

API Docs

useUrlEncode hook for React.js

API Docs

encodeState and decodeState helpers

API Docs

encode and decode helpers

API Docs

Best Practices

  • Define your state shape as a constant
  • Use TypeScript for enhanced type safety and autocomplete
  • Avoid storing sensitive information in URL parameters (SSN, API keys etc)
  • Use this extension for readable TS errors

Can create state hooks for slices of state, and reuse them across application. For example:

type UserState = {
  name: string;
  age: number;
  other: { id: string, value: number }[]
};
const userState = {
  name: '',
  age: 0,
  other: [],
};

export const useUserState = () => {
  const { urlState, setUrl, reset } = useUrlState(userState);

  // other logic

  // reset query params when navigating to other page
  React.useEffect(() => {
    return reset
  }, [])

  return { userState: urlState, setUserState: setUrl };;
}

Gotchas

  1. Can pass only serializable values, Function, BigInt or Symbol won't work, probably things like ArrayBuffer neither. Everything that can be serialized to JSON will work.
  2. Vercel servers limit size of headers (query string and other stuff) to 14KB, so keep your URL state under ~5000 words. https://vercel.com/docs/errors/URL_TOO_LONG
  3. Tested with next.js 14/15 with app router, no plans to support pages.

Other

Contribute and/or run locally

See Contributing doc

Roadmap

  • [x] hook for Next.js
  • [x] hook for react-router
  • [x] hook for remix
  • [ ] hook for svelte
  • [ ] hook for astro
  • [ ] hook for store state in hash ?

Contact & Support

  • Create a GitHub issue for bug reports, feature requests, or questions

Changelog

License

This project is licensed under the MIT license.

Inspiration

NUQS

Using URL to store state in Vue

Storing state in the URL

NextJS useSearchParams

更新履歴

5.1.0 (2025-06-19)

Features

  • rollup: enable CJS output (bde2bf1)

5.0.0 (2025-06-16)

Code Refactoring

  • remove deprecated params format (bd24bf9)

Features

  • remix: example for remix@2 with SSR (8f0bd48)

BREAKING CHANGES

  • old format useUrlState(allParamsObj) is removed. Use format described in a documentation, it uses new format for a while.

4.3.3 (2025-06-07)

Bug Fixes

  • useurlstatebase: fix possible empty upd issue (e87f091), closes #57

4.3.2 (2025-05-14)

Bug Fixes

  • fix basename for react-router, second try (38d8c3f), closes #52

4.3.1 (2025-05-09)

Bug Fixes

  • use basename for react-router (ef0e90a), closes #52

4.3.0 (2025-04-04)

Bug Fixes

Features

4.2.0 (2025-04-04)

Features

4.2.0 (2025-04-04)

Features

4.1.17 (2025-04-04)

Bug Fixes

4.1.16 (2025-04-04)

Bug Fixes

  • bump version, yarn not always correctly resolve it (46308bc)

4.1.15 (2025-04-04)

Bug Fixes

4.1.14 (2025-04-04)

Bug Fixes

  • fix esbuild minification bug (dc8112d)

4.1.13 (2025-04-04)

Bug Fixes

  • fix parsing qs params on the client (c71d690)

4.1.12 (2025-04-04)

Bug Fixes

  • update rollup and esbuild (03e865b)

4.1.11 (2025-04-01)

Bug Fixes

4.1.10 (2025-01-30)

Bug Fixes

4.1.9 (2025-01-30)

Bug Fixes

  • reset state independent from URL in 'reset' cb (9392a19)

4.1.8 (2024-12-10)

Bug Fixes

  • fix bug with state out of sync with useHistory: true (072712f)

4.1.7 (2024-11-28)

Bug Fixes

4.1.6 (2024-11-26)

Bug Fixes

  • update description, bump (be080bf)

4.1.5 (2024-11-24)

Bug Fixes

4.1.4 (2024-11-24)

Bug Fixes

  • minor fixes, works for react-router@7 as well (2993f9a)

4.1.3 (2024-11-21)

Bug Fixes

  • use esbuild instead of terser (59226b0)

4.1.2 (2024-11-20)

Bug Fixes

  • fix history pushState/replaceState rate limits (35d1398)

4.1.1 (2024-11-18)

Bug Fixes

4.1.0 (2024-11-15)

Features

  • useurlstate: return reset cb from useUrlState, it can reset state and URL to default (68fc693)

4.0.9 (2024-11-14)

Bug Fixes

  • fix setUrl options as second argument (2347850)

4.0.8 (2024-11-13)

Performance Improvements

  • minor performance improvements, regex in replaceAll (b89406d)

4.0.7 (2024-11-10)

Bug Fixes

  • fix single quote encoding (8e768b6)

4.0.6 (2024-11-10)

Bug Fixes

  • use first argument for defaultState and second as object with other options (b896d5f)

4.0.5 (2024-11-09)

Bug Fixes

  • return urlState as normal type, not readonly (a0aa6dd)

4.0.4 (2024-11-07)

Bug Fixes

4.0.3 (2024-11-06)

Bug Fixes

4.0.2 (2024-11-03)

Bug Fixes

  • update tags and description (56c634c)

4.0.1 (2024-11-02)

Bug Fixes

4.0.0 (2024-11-02)

Features

  • useHistory option to use native window.history instead of Next.js router, true by default (6cb1a41)

BREAKING CHANGES

  • For Next.js, useUrlState hook will use window.history for navigation by default, to opt out pass useUrlState({ useHistory: false })

3.1.0 (2024-11-02)

Features

  • rename APIs, keep old ones for backward compatibility (a4be099)

Performance Improvements

  • way faster URL updates, can use updateUrl by default (1920de8)

3.0.7 (2024-10-29)

Bug Fixes

3.0.6 (2024-10-27)

Bug Fixes

3.0.5 (2024-10-22)

Bug Fixes

3.0.4 (2024-10-16)

Bug Fixes

  • update sitemap and description (c68d45e)

3.0.3 (2024-10-12)

Bug Fixes

3.0.1 (2024-10-01)

Bug Fixes

3.0.0 (2024-09-30)

Code Refactoring

  • useurlstate: remove deprecated things (87c8c7c)

Features

  • useurlstate: useUrlState hook for react-router@6 (1c7cd02)

BREAKING CHANGES

  • useurlstate: 1. useUrlState for Next.js now accept only object, eg. useUrlState({ defaultState: {}})
    1. urls encoded with versions prior to v2.3.0 could stop working

2.6.0 (2024-09-19)

Bug Fixes

Features

2.5.2 (2024-09-09)

Bug Fixes

2.5.1 (2024-09-09)

Bug Fixes

  • semantic-release config (659e605)

2.5.1 (2024-09-09)

Bug Fixes

  • semantic-release config (659e605)

2.5.1 (2024-09-09)

Bug Fixes

  • semantic-release config (659e605)

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

2.4.1 (2024-09-08)

Features

  • improve encoder algo, smaller URI strings and less complexity (193e8c7)
  • provenance test (111e096)
  • semantic release (235b422)
  • test release (8c56246)

2.4.0 (2024-09-08)

Features

  • improve encoder algo, smaller URI strings and less complexity (193e8c7)
  • semantic release (235b422)
  • test release (8c56246)

Changelog

All notable changes to this project will be documented in this file. Dates are displayed in UTC.

Generated by auto-changelog.

v2.3.0

  • ci: semantic-release config 7aa63ab
  • refactor: refactor common components 17ca72f
  • ci: release-it 84165ba

v2.3.0

6 September 2024

  • refactor: refactor components, styles and test #9
  • build(deps): bump micromatch and lint-staged #8
  • style: next page optimization 9ec0bf9
  • chore: bot detection 8281d85
  • feat: improve encoder algo, smaller URI strings and less complexity 193e8c7

v2.2.5

21 August 2024

v2.2.4

18 August 2024

  • refactor(useurlstatebase): use getInitialState as proper dependency injection 38444e6
  • chore(release): 2.2.4 ecdd628
  • docs: Update README.md 9a67bfc

v2.2.3

15 August 2024

  • docs: rename github to docs in JSDoc comments 6f78f6d
  • chore(release): 2.2.3 37164ff

v2.2.2

15 August 2024

  • fix: fix nested Date serialization e5451d5
  • chore: remove unused package 40f8465
  • docs: attempt to fix vercel error aafbfd4

v2.2.1

12 August 2024

v2.2.0

9 August 2024

  • feat(useurlstate): replace=true by default, object args b531063
  • chore: update test utils c022d7f
  • docs: note about onBlur 14f4e7c

v2.1.1

6 August 2024

  • test: separate stateShape obj instance for each test 9684408
  • style: url box and some style fixes 7baaab4
  • refactor: minor refactor 2742e0b

v2.1.0

3 August 2024

  • test: exports test 1503aeb
  • feat: allow to use partial value for updateState/updateUrl 1e0ede3
  • test: upgrade playwright f659243

v2.0.2

1 August 2024

  • docs: update README translations e159666
  • fix(useurlstate): ignore/preserve sp not defined in stateShape 502c4e3
  • test: minor test refactor d97d03b

v2.0.1

1 August 2024

v2.0.0

31 July 2024

  • feat: Integrations with nextJS, subpatch exports #7
  • refactor: useUrlStateBase hook 72afbda
  • test: tests for useUrlState with few components 868cfca
  • docs: update docs 78c64ba

v1.2.0

25 July 2024

v1.1.0

23 July 2024

  • feat: useSharedState hook for Next.js/React #6
  • chore: fix html import 5c105f4
  • chore: empty react+ts vite example cab1531
  • chore: render React SPA under /react route 672fc25

v1.0.2

20 July 2024

  • test: split test and skip hydrations errors for now 4e8ac57
  • fix: fix value getting for SSR b1996a1
  • style: style improvement 96c667a

v1.0.1

17 July 2024

  • docs: kO and CN tranlation of main Readme #5
  • style: landing improvements fcf9746
  • style: openGraph meta tags 9a0435b
  • chore: some SEO stuff 39bbfdd

v1.0.0

14 July 2024

v0.2.7

13 July 2024

  • Docs #4
  • docs: markdown documentation for all exported functions 723c584
  • style: udpate eslint plugin and fix linting 0a250ac
  • test: remount component test f751f8e

v0.2.6

12 July 2024

v0.2.5

11 July 2024

  • refactor: move eventLIsterner logic to state.ts de6a348
  • docs: improve README e685cc3
  • chore: bump example e9cd152

v0.2.4

10 July 2024

  • fix: fix history navigation, add more tests f54d893
  • build: add playwright watch script 853a1ad
  • refactor: minor clean up 38748ec

v0.2.3

9 July 2024

v0.2.2

9 July 2024

  • fix: fix import, no type module, and cjs bundle too ccb428b
  • fix: updateState on updateUrl and fix types 59c8250
  • chore(release): 0.2.2 6f67a39

v0.2.1

8 July 2024

  • docs: Create CODE_OF_CONDUCT.md c1f75db
  • docs: Update issue templates e356927
  • chore: vercel analytics ba65f49

v0.2.0

8 July 2024

  • feat: observer pattern to communicate between useUrlState hooks, stateShape parameter required f8d8db1
  • ci: disable github-pages deploy 5d23c91
  • docs: improve readme bfa059c

v0.1.7

5 July 2024

  • feat: use fallback for invalid/incomplet URL string 7690030
  • docs: import types definitions 8427fad
  • docs: explicit types in nextjs example 921a160

v0.1.6

3 July 2024

  • feat: use fallback for invalid/incomplet URL string f6558ce
  • docs: import types definitions 9a9e879
  • docs: explicit types in nextjs example a8677f7

v0.1.5

2 July 2024

v0.1.4

2 July 2024

  • feat: encodeState and decodeState functions abc4dcb
  • chore(release): 0.1.4 e3e802b
  • chore: fix tsconfig/eslint e336827

v0.1.3

1 July 2024

  • fix: keep scroll for router.push, add option for router.replace 6e9646e
  • ci: bump lib in example cafcdee
  • chore(release): 0.1.3 1c57e02

v0.1.2

1 July 2024

  • style: redesign of demo page 935b68f
  • ci: change nextjs directory 20fefe0
  • ci: gh-pages another action c6fc97f

v0.1.1

30 June 2024