Laravel 9 Api with Vue 3 Composition Api Image Upload Example

In this tutorial we will see laravel 9 rest api with vue 3 composition api image file upload. In vue 3 file upload we will use axios. Before we start we need to setup laravel api with vue 3.

Laravel 9 Backend Api Connect with Vue 3 Using Axios Example

Laravel 9 Rest Api Image Upload with Validation Example

Create Laravel Project

Install fresh laravel app and connect to database.

composer create-project --prefer-dist laravel/laravel image-upload

Create Image Model and Migration

Run shorthand command to create image modal, migration and controller.

php artisan make:model Image -mc 


public function up()
    Schema::create('images', function (Blueprint $table) {



namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Image extends Model
    use HasFactory;
    protected $fillable = [

Create Image Api Controller and Route

Create Image Api Controller by running below command.

php artisan make:controller Api/ImageController  

First you need to import Image class and import use Symfony\Component\HttpFoundation\Response;



namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Image;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class ImageController extends Controller
    public function imageStore(Request $request)
        $this->validate($request, [
            'image' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:2048',
        $image_path = $request->file('image')->store('image', 'public');

        $data = Image::create([
            'image' => $image_path,

        return response($data, Response::HTTP_CREATED);

Now you need to set api.php route.



use App\Http\Controllers\Api\ImageController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('image',[ImageController::class, 'imageStore']);

Migrate database & Storage links

run migrate database

php artisan migrate

Storage links to public directory.

php artisan storage:link

run the laravel server

php artisan serve

Image Upload with Vue 3 Composition Api Using Laravel REST API

Create vue 3 project.

npm init [email protected]

Select your requirements.

Vue.js - The Progressive JavaScript Framework
 Project name:  frontend
 Add TypeScript?  No / Yes
 Add JSX Support?  No / Yes
 Add Vue Router for Single Page Application development?  No / Yes
 Add Pinia for state management?  No / Yes
 Add Vitest for Unit Testing?  No / Yes
 Add Cypress for both Unit and End-to-End testing?  No / Yes
 Add ESLint for code quality?  No / Yes
 Add Prettier for code formatting?  No / Yes
Scaffolding project in /vue-project/frontend...
Done. Now run:
 cd frontend
 npm install
npm run dev

Install axios In Vue 3

Run below command to install vue-axios

npm i vue-axios

Install Tailwind CSS in Vue 3

How to Install Tailwind CSS in Vue 3


Read Tailwind Official Doc

Create image vue router


import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import Image from '../views/Image.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
      path: '/',
      name: 'home',
      component: HomeView
      path: '/image',
      name: 'image',
      component: Image
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/AboutView.vue')

export default router

Vue 3 composition api image upload with axios using laravel api.


import { ref } from 'vue';
import axios from 'axios';
import { useRouter } from 'vue-router';
export default {
  setup() {
    const image = ref('');
    const router = useRouter();

    const onFileChange = (e) => {
      image.value =[0];
    const submit = async () => {
      if (!image.value) {
        alert('please fill the filed');
      } else {
        const formdata = new FormData();
        formdata.append('image', image.value);
        ).then(() => {
            name: 'name',
        .catch((error) => {

    return {submit,onFileChange};
  <div class="flex items-center justify-center h-screen">
    <div class="w-1/3">
      <form @submit.prevent="submit">
        <div class="mb-4">
            class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"
        <button class="px-6 py-1.5 text-white bg-blue-600" type="submit">
laravel 9 api with vue 3 composition api image upload

laravel 9 api with vue 3 composition api image upload

Run vue server

npm run dev

Show image

<img :src="`http://localhost:8000/storage/${image.image}`"/>