API Reference

Canonical naming in v4: validationMode, optimisticData,submitErrors, actionResult.

Legacy aliases are still supported for backward compatibility (clientValidation, optimisticReducer, serverErrors, lastResult, setServerError, clearPersisted).

useActionForm (Next.js)

import { useActionForm } from 'hookform-action'

Bridges React Hook Form with a Next.js Server Action.

function useActionForm<TFieldValues, TResult>(
  action: ServerAction<TResult>,
  options?: UseActionFormOptions<TFieldValues, TResult>
): UseActionFormReturn<TFieldValues, TResult>

Options

OptionTypeDefaultDescription
defaultValuesDefaultValues<T>Initial form values.
modeMode'onSubmit'RHF validation mode.
persistKeystringEnables sessionStorage persistence.
persistDebouncenumber300Debounce interval (ms) for persistence.
errorMapperErrorMapper<T>defaultErrorMapperCustom error extractor.
onSuccess(result) => voidCalled after successful submission.
onError(result | Error) => voidCalled on error.
schemaZodSchemaZod schema for client-side validation. Auto-detected from withZod.
validationModeClientValidationMode'onSubmit''onChange' | 'onBlur' | 'onSubmit'.
optimisticKeystringEnables optimistic UI.
optimisticData(current, formData) => TReducer for optimistic state.
optimisticInitialTInitial data for optimistic state.

useActionForm (Standalone)

import { useActionForm } from 'hookform-action-standalone'

v4Same API, but takes an options object with submit instead of a Server Action.

function useActionForm<TFieldValues, TResult>(
  options: UseStandaloneActionFormOptions<TFieldValues, TResult>
): UseStandaloneActionFormReturn<TFieldValues, TResult>

Additional Options

OptionTypeDescription
submit(data: T) => Promise<TResult>Required. The async function that handles form submission. Replaces the Server Action argument.

All other options (defaultValues, schema, validationMode,persistKey, optimisticKey, etc.) are identical to the Next.js version. The return type is the same except there is no formAction property.

useActionFormCore

import { useActionFormCore } from 'hookform-action-core/core'

v4Framework-agnostic core hook. Adapters (Next.js, standalone) wrap this. Use directly only for building custom adapters.

function useActionFormCore<TFieldValues, TResult>(
  submit: SubmitFunction<TFieldValues, TResult>,
  options?: UseActionFormCoreOptions<TFieldValues, TResult>
): UseActionFormCoreReturn<TFieldValues, TResult>

Return Value

Returns everything from React Hook Form's useForm, plus:

Need a full timeline and state-by-state guide? See Submit Lifecycle.

PropertyTypeDescription
handleSubmit(onValid?) => handlerEnhanced submit handler.
formState.isSubmittingbooleanSubmit-in-progress flag (RHF + internal action state). Prefer isPending for UX locking/loading.
formState.isPendingbooleanTrue while transition/request is pending. Primary state for disabled buttons and spinners.
formState.isSubmitSuccessfulbooleanTrue when the last completed submit succeeded (no field errors).
formState.submitErrorsFieldErrorRecord | nullStructured field errors from validation/client mapping.
formState.actionResultTResult | nullFull result from the last completed action response (use with success guards).
setSubmitError(field, msg) => voidManually set a server error on a field.
persist() => voidManually persist to sessionStorage.
clearPersistedData() => voidClear persisted data.
formAction(FormData) => PromiseNext.js only. Direct form action for <form action={…}>.
optimisticOptimisticState<T> | undefinedOptimistic state with data, isPending, rollback().

<Form />

Headless wrapper providing RHF FormContext. Works with both adapters.

<Form
  form={formReturn}
  onValid={(data) => console.log(data)}
  className="space-y-4"
>
  <input {...form.register('email')} />
  <button type="submit">Submit</button>
</Form>

Props

PropTypeDescription
formUseActionFormReturn | UseActionFormCoreReturnReturn value from useActionForm (any adapter).
onValid(data) => voidOptional callback before action is called.
...restHTMLFormAttributesAll standard <form> attributes.

Utilities

Persistence Helpers

import {
  loadPersistedValues,
  savePersistedValues,
  clearPersistedValues,
} from 'hookform-action-core'

const data = loadPersistedValues<MyForm>('my-key')
savePersistedValues('my-key', { email: 'a@b.com' })
clearPersistedValues('my-key')

withZod

Wraps a Server Action with Zod validation. The schema is auto-detected on the client.

import { withZod } from 'hookform-action-core/with-zod'
// or: import { withZod } from 'hookform-action-core/zod'

const action = withZod(schema, async (data) => {
  // data is fully typed
  return { success: true }
})

defaultErrorMapper

import { defaultErrorMapper } from 'hookform-action-core'

const customMapper = (result) => {
  const zodErrors = defaultErrorMapper(result)
  if (zodErrors) return zodErrors
  // Handle custom format...
  return null
}

Plugin System (Internal)

v4Internal plugin architecture for extending useActionFormCore. Not yet part of the public API.

interface ActionFormPlugin<TFieldValues, TResult> {
  name: string
  onBeforeSubmit?: (data) => boolean | Promise<boolean>
  onSuccess?: (result, data) => void
  onError?: (error, data) => void
  onMount?: () => (() => void) | void
}
LifecycleWhen it runs
onBeforeSubmitBefore submit. Return false to block submission.
onSuccessAfter successful submission (no field errors).
onErrorAfter failed submission or thrown error.
onMountOn mount. Return cleanup function for unmount.

Packages

PackageVersionPurpose
hookform-action-core4.0.3Core + Next.js adapter (backward-compatible)
hookform-action4.0.3Standalone Next.js adapter package
hookform-action-standalone4.0.3Adapter for Vite, Remix, Astro, SPAs
hookform-action-devtools4.0.3Floating debug panel (FormDevTool)

MIT License · Built with ♥ for the React community