Forms

Submitting forms

While it's possible to make classic form submissions with Inertia, it's not recommended, as they cause full page reloads. Instead, it's better to intercept form submissions and then make the request using Inertia.

<template>
  <form @submit.prevent="submit">
    <label for="first_name">First name:</label>
    <input id="first_name" v-model="form.first_name" />
    <label for="last_name">Last name:</label>
    <input id="last_name" v-model="form.last_name" />
    <label for="email">Email:</label>
    <input id="email" v-model="form.email" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        first_name: null,
        last_name: null,
        email: null,
      },
    }
  },
  methods: {
    submit() {
      this.$inertia.post('/users', this.form)
    },
  },
}
</script>

Unlike a classic ajax submitted form, with Inertia you don't handle the post submission behaviour client-side. Rather, you do this server-side using a redirect. And, of course, there is nothing stopping you from redirecting right back to the page that you're on.

class UsersController extends Controller
{
    public function index()
    {
        return Inertia::render('Users/Index', [
          'users' => User::all(),
        ]);
    }

    public function store()
    {
        User::create(
            Request::validate([
                'first_name' => ['required', 'max:50'],
                'last_name' => ['required', 'max:50'],
                'email' => ['required', 'max:50', 'email'],
            ])
        );

        return Redirect::route('users');
    }
}

File uploads

The trick to uploading files with Inertia is using the FormData object, since that's what's required to submit a multipart/form-data request via XHR. Here is a simple example of using FormData with Inertia.

var data = new FormData()
data.append('name', name || '')
data.append('email', email || '')
data.append('password', password || '')
data.append('is_admin', is_admin ? '1' : '0')
data.append('photo', photo || '')

Inertia.post('/users', data)
However, as of version 0.8.0, Inertia automatically detects if the visit includes any files (even nested files), and then converts the data to a FormData object if needed.

You can learn more about the FormData interface here.

Form helper

Since working with forms is so common, Inertia comes with a form helper designed to help reduce the amount of boilerplate needed for typical forms. Here's how to use it:

<template>
  <form @submit.prevent="form.post('/login')">
    <!-- email -->
    <input type="text" v-model="form.email">
    <div v-if="form.errors.email">{{ form.errors.email }}</div>
    <!-- password -->
    <input type="password" v-model="form.password">
    <div v-if="form.errors.password">{{ form.errors.password }}</div>
    <!-- remember me -->
    <input type="checkbox" v-model="form.remember"> Remember Me
    <!-- submit -->
    <button type="submit" :disabled="form.processing">Login</button>
  </form>
</template>

<script>
/*
|----------------------------------------------------------------
| Vue 3
|----------------------------------------------------------------
*/

import { useForm } from '@inertiajs/inertia-vue3'

export default {
  setup () {
    const form = useForm({
      email: null,
      password: null,
      remember: false,
    })

    return { form }
  },
}

/*
|----------------------------------------------------------------
| Vue 2
|----------------------------------------------------------------
*/

export default {
  data() {
    return {
      form: this.$inertia.form({
        email: null,
        password: null,
        remember: false,
      }),
    }
  },
}
</script>

To submit the form, use the get, post, put, patch and delete methods.

form.get(url, options)
form.post(url, options)
form.put(url, options)
form.patch(url, options)
form.delete(url, options)

The submit methods support all the regular visit options, such as preserveState, preserveScroll, and the event callbacks. This can be helpful for performing tasks on successful form submissions, such as resetting inputs.

form.post('/profile', {
  preserveScroll: true,
  onSuccess: () => form.reset('password'),
})

If you need to modify the form data before it's sent to the server, you can do this via the transform() method.

form
  .transform((data) => ({
    ...data,
    remember: data.remember ? 'on' : '',
  }))
  .post('/login')

You can use the processing property to track if a form is currently being submitted. This can be helpful for preventing double form submissions, by disabling the submit button.

<button type="submit" :disabled="form.processing">Submit</button>

In the event that you're uploading files, the current progress event is available via the progress property. This is helpful for showing upload progress. For example:

<progress v-if="form.progress" :value="form.progress.percentage" max="100">
  {{ form.progress.percentage }}%
</progress>

In the event there are form errors, they are available via the errors property.

<div v-if="form.errors.email">{{ form.errors.email }}</div>

To check if a form has any errors, use the hasErrors property. To clear form errors, use the clearErrors() method.

// Clear all errors
form.clearErrors()

// Clear errors for specific fields
form.clearErrors('field', 'anotherfield')

When a form has been successfully submitted, the wasSuccessful property will be true. In addition to this, there is also a recentlySuccessful property, which will be set to true for two seconds after a successful form submission. This is helpful for showing temporary success messages.

To reset the form values back to their original values, use the reset() method. Note, this will reset the values back to the initial values that were provided when you first instantiated the form helper.

// Reset the form
form.reset()

// Reset specific fields
form.reset('field', 'anotherfield')

Server-side validation

Handling server-side validation errors in Inertia works a little different than a classic ajax-driven form, where you catch the validation errors from 422 responses and manually update the form's error state. That's because Inertia never receives 422 responses. Rather, Inertia operates much more like a standard full page form submission. See the validation page for more information.

Classic XHR submits

Using Inertia to submit forms works well for the vast majority of situations. However, in the event that you'd like more fine-grain control over the form submission, there's nothing stopping you from making a classic XHR request. An excellent library to use here is axios, which is what Inertia uses under the hood.