Type-safe URL Search Params
parseURLSearchParam
is a small utility function that validates and transforms
URL search parameters into a structured object based on a given
zod schema.
Helpful for handling URL parameters in TypeScript, ensuring data conforms to a specified structure and type through validation. This is especially useful in web applications where data from URLs needs to be clean, type-safe, and conform to expected formats.
import { z } from "zod";
export function parseURLSearchParams<T extends z.ZodTypeAny>(
schema: T,
params: URLSearchParams,
) {
const data: Record<string, string[] | string | undefined> = {};
for (const key of params.keys()) {
const value = params.getAll(key).filter(v => v !== String(undefined));
if (value.length > 1) data[key] = value;
else data[key] = value.at(0);
}
return schema.parse(data) as z.infer<T>;
}
Example usage
import { z } from "zod";
/** Pagination - current page number */
const zCurrentPage = z.coerce.number().positive().min(1).default(1).catch(1);
/** Sort direction */
const zDirection = z.enum(["ASC", "DESC"]).default("DESC").catch("DESC");
/** Sort by field */
const zSortBy = z.enum(["NAME", "PRICE", "CREATE_DATE"]).catch("PRICE");
const zStringArray = z
.string()
.array()
.or(z.string())
.optional()
.transform(v => (typeof v === "string" ? [v] : v));
const ProductFilterSchema = z.object({
search: z.string().optional(),
page: zCurrentPage,
sortBy: zSortBy,
direction: zDirection,
productVariants: zStringArray,
});
import { useSearchParams } from "react-router-dom";
function Component() {
const [searchParams] = useSearchParams();
const filters = parseURLSearchParams(ProductFilterSchema, searchParams);
return (
<div>
<ProductList filters={filters} />
</div>
);
}