Upload Files and other input together with Inertia/Vue/Laravel

Dr. Adam Nielsen
1 min readNov 14, 2023

--

Imagine you have an edit page where you can specify name and an image:

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

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

function submit() {
form.put('/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>

Note, we cant use `<input type=”file” v-model=”form.avatar” />` as Vue does not allow this for input with type file.

Whenever a file is present in the input, Inertija will convert the whole request to a FormRequest. Unfortunatly, Laravel does not support FormData request using PUT .

The effect is, that name would simply be not present, whenever a file is selected.

To fix this, you can add form method spoofing to the form object like this:

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

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

function submit() {
form.put('/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>

Although Inertia.js sends this out sometimes as a FormData or as a regular request, its always accessible like this on the Illuminati/Http/Request:

$request->input('name');
$request->file('avatar');

Hope it helps :)

--

--