# useHiddenFieldResolvers

URL: https://docs.forms.saastro.io/docs/use-hidden-field-resolvers
> Resolves hidden field values at form mount — timestamps, URLs, IP addresses, and UTM parameters.

# useHiddenFieldResolvers

Resolves all hidden field values when the form mounts. Filters fields with `type: 'hidden'`, runs their resolvers in parallel, and sets the values via `react-hook-form`'s `setValue`.

> **You probably don't need this directly.** It runs automatically inside [`useFormState`](/docs/use-form-state) (and therefore inside `<Form />`). Use it only when building a custom form renderer that needs to support hidden fields.

---

## Signature

```tsx

useHiddenFieldResolvers(methods, fields);
```

---

## Parameters

| Parameter | Type                                     | Required | Description                                    |
| --------- | ---------------------------------------- | -------- | ---------------------------------------------- |
| `methods` | `UseFormReturn<Record<string, unknown>>` | Yes      | react-hook-form instance from `useForm()`      |
| `fields`  | `Fields`                                 | Yes      | Form field configurations from `config.fields` |

---

## Return Value

This hook returns `void`. It operates as a side-effect only — setting hidden field values via `methods.setValue()`.

---

## How It Works

1. On mount (and again if `fields` or `methods` change), filters all fields where `type === 'hidden'` — if there are none, it does nothing
2. Runs all resolvers concurrently via `Promise.all` and `resolveValue()`
3. Sets each value with `setValue(name, value, { shouldDirty: false })`
4. Cleanup function prevents stale writes if the component unmounts before resolvers complete

Most resolvers produce their value instantly (timestamp, hostname, pageUrl, referrer, userAgent, urlParam). The `ip` resolver uses `fetch` and is genuinely async. All run concurrently regardless.

---

## Example

```tsx

function CustomFormRenderer({ config }: { config: FormConfig }) {
  const methods = useForm<Record<string, unknown>>({ defaultValues: {} });

  // Resolves hidden field values on mount
  useHiddenFieldResolvers(methods, config.fields);

  const onSubmit = (values: Record<string, unknown>) => {
    console.log(values); // includes the resolved hidden values
  };

  return (
    <form onSubmit={methods.handleSubmit(onSubmit)}>
      {/* Render visible fields... */}
      {/* Hidden fields render nothing, but their values are in form state */}
    </form>
  );
}
```

---

## Built-in Resolvers

| Resolver    | Async | Output                                                                                     |
| ----------- | ----- | ------------------------------------------------------------------------------------------ |
| `timestamp` | No    | ISO 8601 string                                                                             |
| `hostname`  | No    | `window.location.hostname`                                                                  |
| `pageUrl`   | No    | `window.location.href`                                                                      |
| `referrer`  | No    | `document.referrer`                                                                         |
| `userAgent` | No    | `navigator.userAgent`                                                                       |
| `urlParam`  | No    | URL query parameter value — options `{ param, fallback? }`                                  |
| `ip`        | Yes   | Visitor IP via `fetch` — options `{ endpoint?, fallback? }` (default `https://api.ipify.org?format=json`) |

Hidden fields accept only these serializable built-ins (`SerializableFieldResolver`) — the function-based `custom` resolver is excluded so configs stay JSON-storable. All resolvers are SSR-safe: when browser globals (`window`, `document`, `navigator`) are unavailable, `urlParam` returns its `fallback` (or an empty string) and the other browser-based resolvers return an empty string. The `ip` resolver returns its `fallback` (or an empty string) if the fetch fails.

---

## Related

- [Hidden Fields](/docs/hidden-fields) — Full guide with resolver configuration, use cases, and examples
- [Hidden field type](/docs/hidden) — Field type reference with interactive demo
