Fetching latest headlines…
Using Vue in Laravel Without Inertia
NORTH AMERICA
🇺🇸 United StatesMay 10, 2026

Using Vue in Laravel Without Inertia

2 views0 likes0 comments
Originally published byDev.to

We can use inertia.js, but sometimes we just need to keep it simple. This also works for React and others.

Folder Structure

# only an example

resources
 ├ js
 │ ├ app.js
 │ ├ App.vue
 │ ├ pages
 │ │ └ Dashboard.vue
 │ ├ components
 │ │ └ ui
 │ └ layouts
 └ views
    └ app.blade.php

# Flow

Laravel route
   ↓
controller returns Blade
   ↓
Blade sets PAGE + PROPS
   ↓
Vue loads correct page component
   ↓
component receives props

Steps

  • Installation
# laravel
laravel new example-app

# vue
npm install vue
npm install @vitejs/plugin-vue --save-dev
  • Vite
# vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
        vue(),
    ],
});
  • Entry
# resources\js\app.js

import { createApp, h } from "vue"
import App from "./App.vue"

const app = createApp({
    render: () => h(App, {
        page: window.PAGE,
        props: window.PROPS
    })
})

app.mount("#vue-app")
  • Root
# resources\js\App.vue

<script setup>
import { defineAsyncComponent } from "vue"
import AppSidebar from "./components/app-sidebar.vue"

const props = defineProps({
    page: String,
    props: Object
})

const pages = import.meta.glob("./pages/**/*.vue")
const loader = pages[`./pages/${props.page}.vue`]
const PageComponent = loader ? defineAsyncComponent(loader) : null
</script>

<template>
    <div class="flex min-h-screen">
        <AppSidebar />

        <main class="flex-1 p-6">
            <component v-if="PageComponent" :is="PageComponent" v-bind="props.props" />
            <div v-else>Page not found</div>
        </main>
    </div>
</template>
  • Connect
# resources\views\layouts\app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name') }}</title>

    <script>
        window.PAGE = @json($page);
        window.PROPS = @json($props);
        window._USER = @json(auth()->user());
        window.APP_NAME = @json(config('app.name'));
    </script>

    @vite(['resources/js/app.js'])

</head>

<body>

    <div id="vue-app"></div>

</body>

</html>
  • Run
# start your web server, and then:

npm run dev
  • Controller
# example

public function index()
{
    return view('app', [
        'page' => 'componentsname',
        'props' => [
            'title' => 'page title',
            'constant' => ['type' => 'monthly']
        ]
    ]);
}

Need help building your app? I’m available for freelance web & Android development — raflizocky.netlify.app

☕ Support my writing: paypal.me/raflizocky · saweria.co/raflizocky

Comments (0)

Sign in to join the discussion

Be the first to comment!