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.
WARNING
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 or a X-HTTP-METHOD-OVERRIDE
header in the request.
NOTE
For more info see Rack::MethodOverride
.
import { router } from '@inertiajs/vue3'
router.post(`/users/${user.id}`, {
_method: 'put',
avatar: form.avatar,
})
// or
form.post(`/users/${user.id}`, {
headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
})