File uploads

FormData conversion

When making Inertia requests that include files (even nested files), Inertia will automatically convert the request data into a FormData object. This conversion is necessary in order to submit a multipart/form-data request via XHR.

If you would like the request to always use a FormData object regardless of whether a file is present in the data, you may provide the forceFormData option when making the request.

import { router } from '@inertiajs/vue3'

router.post('/users', data, {
  forceFormData: true,
})

You can learn more about the FormData interface via its MDN documentation.

Prior to version 0.8.0, Inertia did not automatically convert requests to FormData. If you're using an Inertia release prior to this version, you will need to manually perform this conversion.

File upload example

Let's examine a complete file upload example using Inertia. This example includes both a name text input and an avatar file input.

<script setup>
import { useForm } from '@inertiajs/vue3'

const form = useForm({
  name: null,
  avatar: null,
})

function submit() {
  form.post('/users')
}
</script>

<template>
  <form @submit.prevent="submit">
    <input type="text" v-model="form.name" />
    <input type="file" @input="form.avatar = $event.target.files[0]" />
    <progress v-if="form.progress" :value="form.progress.percentage" max="100">
      {{ form.progress.percentage }}%
    </progress>
    <button type="submit">Submit</button>
  </form>
</template>

This example uses the Inertia form helper for convenience, since the form helper provides easy access to the current upload progress. However, you are free to submit your forms using manual Inertia visits as well.

Multipart limitations

Uploading files using a multipart/form-data request is not natively supported in some server-side frameworks when using the PUT,PATCH, or DELETE HTTP methods. The simplest workaround for this limitation is to simply upload files using a POST request instead.

However, some frameworks, such as Laravel and Rails, support form method spoofing, which allows you to upload the files using POST, but have the framework handle the request as a PUT or PATCH request. This is done by including a _method attribute in the data of your request.

import { router } from '@inertiajs/vue3'

router.post(`/users/${user.id}`, {
  _method: 'put',
  avatar: form.avatar,
})