Skip to content

withQueryParams

Edit

Adds, replaces, repeats, or removes URL query parameters.

withQueryParams.ts
export type QueryValue =
| string
| number
| boolean
| null
| undefined
| readonly (string | number | boolean)[];
/** Adds, replaces, or removes query parameters while preserving relative URLs and hashes. */
export const withQueryParams = (
input: string | URL,
params: Readonly<Record<string, QueryValue>>
): string => {
const original = String(input);
const hashIndex = original.indexOf("#");
const hash = hashIndex < 0 ? "" : original.slice(hashIndex);
const beforeHash = hashIndex < 0 ? original : original.slice(0, hashIndex);
const queryIndex = beforeHash.indexOf("?");
const base = queryIndex < 0 ? beforeHash : beforeHash.slice(0, queryIndex);
const searchParams = new URLSearchParams(queryIndex < 0 ? "" : beforeHash.slice(queryIndex + 1));
for (const [key, value] of Object.entries(params)) {
searchParams.delete(key);
if (value == null) continue;
const values = Array.isArray(value) ? value : [value];
for (const item of values) searchParams.append(key, String(item));
}
const query = searchParams.toString();
return `${base}${query ? `?${query}` : ""}${hash}`;
};
Terminal
wget -O src/lib/withQueryParams.ts https://raw.githubusercontent.com/jrTilak/lazykit/HEAD/registry/functions/withQueryParams.ts
withQueryParams.example.ts
import { withQueryParams } from "./withQueryParams";
const url = withQueryParams("/search?q=old#results", {
q: "new value",
page: 2,
tag: ["typescript", "bun"]
});
  • input (string | URL) — Absolute, protocol-relative, or relative URL.
  • params — Strings, numbers, booleans, arrays, or nullish removals.
  • The original hash and relative URL form are preserved.