Skip to content

Single Parameter

Use createSearchParamStore to manage one query parameter. Pass a preset for type-safe decode/encode.

import { createQsUtils } from "@vp-tw/nanostores-qs";
import * as presets from "@vp-tw/nanostores-qs/presets";
const qsUtils = createQsUtils();
const pageStore = qsUtils.createSearchParamStore("page", presets.integer({ default: 1, min: 0 }));
const searchStore = qsUtils.createSearchParamStore("q", presets.string({ optional: true }));
const sortStore = qsUtils.createSearchParamStore(
"sort",
presets.enum(["newest", "oldest", "popular"]),
);
const archivedStore = qsUtils.createSearchParamStore("archived", presets.boolean());
import { useStore } from "@nanostores/react";
const page = useStore(pageStore.$value); // number (1 when absent)
const search = useStore(searchStore.$value); // string | undefined
pageStore.update(42); // pushState
pageStore.update(42, { replace: true }); // replaceState
pageStore.update(NaN); // removes "page" from URL

.dry() returns the next search string without modifying the URL — useful for link building.

const nextSearch = pageStore.update.dry(100); // "?page=100"

Try interacting with the controls below — watch the URL update in real time.

Single Parameter Stores with Presets
Store values
{
  q: undefined,
  'page.$value': '',
  'page.$resolved': 1,
  sort: 'newest',
  archived: false
}
window.location.search
(empty)

Use the default option to override a type’s inherent default. For example, presets.integer() defaults to NaN, but a page number should default to 1:

// Without default — page is NaN when absent
const pageStore = qsUtils.createSearchParamStore("page", presets.integer({ min: 0 }));
// With default — page is 1 when absent
const pageStore = qsUtils.createSearchParamStore("page", presets.integer({ default: 1, min: 0 }));

The default option works alongside other options:

presets.integer({ round: "ceil", default: 0 }); // Math.ceil, default 0
presets.float({ fixed: 2, default: 0 }); // 2 decimal places, default 0

When a value equals the preset’s defaultValue, the parameter is removed from the URL to keep it clean. For example, boolean() removes archived when false.