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(and therefore inside<Form />). Use it only when building a custom form renderer that needs to support hidden fields.
Signature
import { useHiddenFieldResolvers } from '@saastro/forms';
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
- On mount (and again if
fieldsormethodschange), filters all fields wheretype === 'hidden'— if there are none, it does nothing - Runs all resolvers concurrently via
Promise.allandresolveValue() - Sets each value with
setValue(name, value, { shouldDirty: false }) - 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
import { useHiddenFieldResolvers } from '@saastro/forms';
import type { FormConfig } from '@saastro/forms';
import { useForm } from 'react-hook-form';
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 — Full guide with resolver configuration, use cases, and examples
- Hidden field type — Field type reference with interactive demo