ix
ix

informatix

PL version Book a discovery call
Home / Blog / Forms and Validation in Inertia.js — useForm Guide [2026]
• 5 min read •

Forms and Validation in Inertia.js — useForm Guide [2026]

The complete Inertia.js form toolkit: the useForm hook, server-side Laravel validation mapped onto fields, error handling, file uploads, progress and dirty-state warnings — with real code.

Forms are where Inertia.js earns its keep. In a classic SPA you rebuild half of Laravel's validation pipeline in JavaScript; with Inertia the rules stay in Laravel and the React side gets a small, complete toolkit for state, errors and submission. This guide covers the patterns we use in production — from a simple create form to file uploads and dirty-state protection.

The useForm hook in 20 lines

import { useForm } from '@inertiajs/react';

export default function CreateOrder({ customers }) {
    const { data, setData, post, processing, errors } = useForm({
        customer_id: '',
        note: '',
    });

    function submit(e) {
        e.preventDefault();
        post('/orders');
    }

    return (
        <form onSubmit={submit}>
            <select value={data.customer_id} onChange={(e) => setData('customer_id', e.target.value)}>
                <option value="">Select a customer…</option>
                {customers.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
            {errors.customer_id && <p className="text-red-500">{errors.customer_id}</p>}

            <textarea value={data.note} onChange={(e) => setData('note', e.target.value)} />
            {errors.note && <p className="text-red-500">{errors.note}</p>}

            <button disabled={processing}>Create order</button>
        </form>
    );
}

The Laravel side is ordinary validation — no special integration

public function store(StoreOrderRequest $request)
{
    Order::create($request->validated());

    return redirect()->route('orders.index')->with('success', 'Order created.');
}

When validation fails, Inertia redirects back with errors attached to props; useForm reads them automatically. Every field stays filled — nothing to preserve manually.

What useForm gives you

Feature What it does
data / setData Reactive form state, single field or whole object
errors Laravel validation errors, keyed by field
processing True while the request is in flight — disable buttons
progress Upload progress (0–100) for file forms
isDirty Whether anything changed — wire it to a leave warning
reset() / clearErrors() Reset after success, clear on field focus
transform() Reshape the payload before submission

File uploads

const { data, setData, post, progress } = useForm({ document: null });

post('/contracts', {
    forceFormData: true, // multipart even for small payloads
});

Inertia submits uploads as multipart automatically when it detects a File. progress feeds a progress bar; Laravel validates the file exactly as in any Blade form (mimes:pdf, max:10240).

The patterns that prevent bugs

Warning: Never spread data into a controlled input you also reset by remounting the component. If the page re-renders with a new key, useForm state is recreated and the user's input disappears — the most common "Inertia ate my form" bug.

  • One useForm per form. Multiple hooks on one page invite state drift; extract sections into components that receive form as a prop instead.
  • Server decides, client displays. Keep business validation in FormRequests; the React side only renders errors. No duplicated rule sets.
  • Disable, do not hide. While processing, disable the submit button — users who double-click otherwise create two orders.
  • Dirty-state guard. Combine isDirty with useEffect to warn before navigating away from unsaved changes.
  • Redirect after success. Return redirect() from the controller — Inertia follows it as a normal page visit and the form state resets with the page.

Testing form flows

Feature tests exercise the same endpoints the form posts to — validation rules, authorization, redirects. On the frontend, component tests cover rendering of errors and disabled states. Our approach is in Testing Inertia.js applications.

When to reach for a form library

Complex wizards with conditional client-side branching, dynamic field arrays and heavy interdependencies between inputs still benefit from Formik or React Hook Form — with useForm handling the final submission. In our projects that is the exception, not the rule: most CRUD forms are cleaner in plain useForm.

Need forms that hold up under real users?

See Laravel development services.

FAQ

How does Inertia.js handle validation errors?

Laravel throws a ValidationException; Inertia redirects back with errors in props; useForm maps them to fields. No manual wiring.

Do I need Formik or React Hook Form?

Rarely. useForm covers state, errors, processing and uploads. Libraries pay off for client-only complexity like multi-step wizards.

Why does my form lose data on validation failure?

Usually because fields live outside useForm or the component remounts with a new key. Keep all state in useForm — it preserves values by design.

👉 Need robust forms in your Laravel app? Check our Laravel development services or hire a Laravel developer.

📖 Read more: Inertia.js with Laravel and React, Inertia.js v2 features and testing Inertia.js applications.

Related posts