@fillament/url-prefill
v0.2.0
Published
Prefill a Fillament form from the URL query string — framework-agnostic, no router dependency. Reads window.location.search (or any params you pass), maps and coerces by your schema, and only fills empty fields by default. Opt-in.
Maintainers
Readme
@fillament/url-prefill
Prefill a Fillament form from the URL query string — framework-agnostic, no router dependency. It reads window.location.search (or any params you pass), maps and coerces values by your schema, and by default skips fields the user has already touched.
pnpm add @fillament/url-prefillTree-shakeable, side-effect-free, SSR-safe. Other URL helpers are tied to React Router or Next; this one just reads the query string, so it works anywhere — Vite SPA, Next, Remix, Astro, plain DOM.
Plugin
import { useForm } from "@fillament/react";
import { zodAdapter } from "@fillament/zod";
import { urlPrefillPlugin } from "@fillament/url-prefill";
// Landing on /[email protected]&plan=pro&seats=3
const form = useForm({
schema: zodAdapter(SignupSchema),
defaultValues,
plugins: [urlPrefillPlugin({ exclude: ["password"] })],
});
// form.email === "[email protected]", form.plan === "pro", form.seats === 3 (coerced to a number)Imperative
import { prefillFromSearch } from "@fillament/url-prefill";
const applied = prefillFromSearch(form); // reads window.location.search
// applied === ["email", "plan", "seats"]
// Or pass an explicit source (SSR, tests, a custom string):
prefillFromSearch(form, { params: "[email protected]&seats=3" });
prefillFromSearch(form, { params: new URL(req.url).searchParams });Behavior
- Coercion by schema. With a validation adapter, string params become their declared types —
seats=3→3,trial=true→true. Dot-path names build nested objects (address.city=London); a repeated param (tag=a&tag=b) becomes an array. - Doesn't clobber edits. A field is prefilled only while it still equals its default — once the user changes it, prefill leaves it alone. Pass
overwrite: trueto force. - Opt-in and scoped. Nothing happens until you add the plugin or call the function. Use
include/excludeandmapto control exactly which params land where. - SSR-safe. With no
paramsand nowindow, it's a no-op and returns[].
Options
| Option | Default | Description |
| --- | --- | --- |
| params | window.location.search | A query string, URLSearchParams, or a record. No-op on the server when omitted. |
| map | identity | { q: "email" } (object: override specific names, others pass through) or (key) => path \| null (function: full control / skip). |
| coerce | true | Coerce strings to schema types. false keeps raw strings. |
| overwrite | false | Overwrite fields the user has changed from their default. |
| include / exclude | — | Allow / skip specific field paths. |
| validate | false | Validate each field as it's set. |
SSR note
The plugin prefills on form init, which runs during render. In a server-rendered app that can cause a hydration mismatch (the server has no URL params, the client does). For SSR, skip the plugin and call prefillFromSearch(form) from a useEffect instead — it runs only on the client, after hydration.
useEffect(() => {
prefillFromSearch(form);
}, [form]);License
MIT © headlessButSmart
