@letar/forms

URL Prefill

Auto-fill form fields from URL query parameters

Overview

useUrlPrefill extracts values from URL parameters and returns them for form initialization. Uses a whitelist for security — only listed fields are extracted.

Quick Example

import { useUrlPrefill } from '@letar/forms'

// URL: /contact?name=Ivan&email=ivan@test.com&hack=evil
const prefilled = useUrlPrefill({
  fields: ['name', 'email'],
  cleanUrl: true,
})
// prefilled = { name: 'Ivan', email: 'ivan@test.com' }
// 'hack' is ignored — not in whitelist

With Form

function ContactForm() {
  const prefilled = useUrlPrefill({
    fields: ['name', 'email', 'phone'],
    cleanUrl: true,
  })

  return (
    <Form
      schema={ContactSchema}
      initialValue={{ name: '', email: '', phone: '', ...prefilled }}
      onSubmit={save}
    >
      <Form.Field.String name="name" />
      <Form.Field.String name="email" />
      <Form.Field.Phone name="phone" />
      <Form.Button.Submit>Send</Form.Button.Submit>
    </Form>
  )
}

Parameter Mapping

Map URL parameter names to form field names:

// URL: /form?user_name=Ivan&mail=ivan@test.com
const prefilled = useUrlPrefill({
  fields: ['name', 'email'],
  mapping: { user_name: 'name', mail: 'email' },
})
// prefilled = { name: 'Ivan', email: 'ivan@test.com' }

Arrays and Nested Objects

// Arrays: /form?tag=react&tag=forms
// → { tag: ['react', 'forms'] }

// Nested: /form?address.city=Moscow&address.street=Tverskaya
// → { address: { city: 'Moscow', street: 'Tverskaya' } }
import { generatePrefillUrl } from '@letar/forms'

const url = generatePrefillUrl('/contact', {
  name: 'Ivan',
  email: 'ivan@test.com',
  tags: ['react', 'forms'],
})
// → "/contact?name=Ivan&email=ivan%40test.com&tags=react&tags=forms"

Props

PropTypeDefaultDescription
fieldsstring[]requiredWhitelist of allowed field names
mappingRecord<string, string>URL param → field name mapping
cleanUrlbooleanfalseRemove params from URL after extraction
schemaZodSchemaValidate extracted values
searchParamsURLSearchParamsautoCustom source (default: window.location)

Live Example

Try the interactive example on forms-example.letar.best.

On this page