Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Anthonysb's avatar

Learning Laravel vue3 inertia, can't figure this out plz help me understand what I'm doing wrong

So another person suggested I try to do my own simple app to learn vue and inertia without using a tutorial or copy pasting anything and only use the documentation, the only thing I copy pasted were npm and composer commands for installation but I can seem to get this thing to load even a sample component. I didn't just install vue with an example component, I installed it after I installed normal Laravel 8 so I could try to learn to do it myself but I keep getting warning from my npm watcher. but nothing from the component is showing.

import Vue from 'vue'
import VueMeta from 'vue-meta'
import { InertiaProgress } from '@inertiajs/progress'
import { createInertiaApp } from '@inertiajs/inertia-vue3'

Vue.config.productionTip = false
Vue.mixin({ methods: { route: window.route } })
Vue.use(VueMeta)

InertiaProgress.init()


createInertiaApp({
    resolve: name => require(`../pages/${name}`),
    setup({ el, app, props }) {
        new Vue({
            metaInfo: {
                titleTemplate: title => (title ? `${title} Generic` : 'App'),
            },
            render: h => h(app, props),
        }).$mount(el)
    },
})

this is my app.js

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix
    .js('resources/js/app.js', 'public/js')
    .vue()
    .alias({ '@': 'resources/js' })
    .postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
]);

this is webpack.mix.js

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Finance App</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
        <link href="{{ mix('/css/app.css') }}" rel="stylesheet" />
        <script src="{{ mix('/js/app.js') }}" defer></script>
        <!-- Styles -->

    </head> <body class="antialiased">
    @if (Route::has('login'))
        <div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
            @auth
                <a href="{{ url('/dashboard') }}" class="text-sm text-gray-700 underline">Dashboard</a>
            @else
                <a href="{{ route('login') }}" class="text-sm text-gray-700 underline">Login</a>

                @if (Route::has('register'))
                    <a href="{{ route('register') }}" class="ml-4 text-sm text-gray-700 underline">Register</a>
                @endif
            @endauth
        </div>
    @endif

    <div id="app" class="flex items-center bg-gray-100 min-h-screen">
       @inertia
    </div>

    </body>
</html>

this is app.blade.php

<template>
    <div>
        <h1>Home Component</h1>
    </div>
    <div>
        <p>
            A falsis, brodium camerarius fermium.Grow quietly like an evil sail.Castus, emeritis medicinas sensim tractare de clemens, audax fluctui.Always esoterically trap the unbiased ego.
        </p>
    </div>

</template>

<script>

export default {
    metaInfo: { title: 'home' },

}

</script>

this is my home.vue file

<?php



namespace App\Http\Controllers;

    use Inertia\Inertia;
    class appController extends Controller

{
    public function index()
    {
        return Inertia::render('pages/home');
    }
}

this is my appController

Route::get('/', [appController::class, 'index'])
    ->name('home')
    ->middleware('auth');

this is my web.php routing

I'm using Laravel 8 vue3 inertia.js and tailwind and I have Laravel breeze as well

WARNING in ./resources/js/app.js 5:0-24 export 'default' (imported as 'Vue') was not found in 'vue' (possible exports: BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId)

WARNING in ./resources/js/app.js 6:0-9 export 'default' (imported as 'Vue') was not found in 'vue' (possible exports: BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId)

WARNING in ./resources/js/app.js 11:0-7 export 'default' (imported as 'Vue') was not found in 'vue' (possible exports: BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId)

WARNING in ./resources/js/app.js 21:8-11 export 'default' (imported as 'Vue') was not found in 'vue' (possible exports: BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId)

webpack compiled with 4 warnings

this is what my watcher is reporting I also don't use chrome so I don't have the vue-devtools(not google's fan at all, and don't want to discuss why) I use safari pretty much exclusively

so if anyone can help I would appreciate it, I'm just trying to learn this

0 likes
15 replies
apex1's avatar

Your versions are not in sync. You're using vue2 but @inertiajs/inertia-vue3. The createInertiaApp({...}) is also the vue2 way of initializing an Inertia app. So you need to choose vue2 or vue3. I suggest you learn Vue outside of Intertia or Laravel, then come back and see how the technologies are integrated.

Anthonysb's avatar

@apex1 that's kinda rude, don't tell someone quit and go learn something else, if you don't have anything constructive please don't say anything. and everything I wrote was according to documentation for vue 3

apex1's avatar

@Anthonysb What the hell are you talking about? You're trying to learn Vue, so I just suggested it'd be easier to focus on Vue outside of a Laravel environment with Inertia, e.g., using vue-cli or vite.

Anthonysb's avatar

@apex1 so if I was learning TALL stack and had a problem with Livewire and alpine would you suggest I go learn Laravel basics again too? I have been able to get a vue app running very basic but I'm trying to learn inertia, that's why it filed under inertia

apex1's avatar

@Anthonysb Well if you read the Vue and Inertia docs you'd know that's not how you initialize a vue3 app. But whatever, good luck on your journey.

Anthonysb's avatar

@apex1 just offer help, not what you just said, nothing you said was positive or constructive to solving my problem and did not help me learn anything. that's why I am upset with your response.

Anthonysb's avatar

@apex1 also this is a straight copy paste from inertiajs.com website for vue3

import { createInertiaApp } from '@inertiajs/inertia-vue3'

createInertiaApp({
  resolve: name => require(`./Pages/${name}`),
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})

and this is my package.json

    },
    "dependencies": {
        "@inertiajs/inertia-vue3": "^0.5.2",
        "@inertiajs/progress": "^0.2.6",
        "vue": "^3.2.20"
    }
}
apex1's avatar

@Anthonysb What you just posted is not the same as your original post. See how in your recent post there is a createApp() function inside the setup() method? That's how you init a Vue3 app, whereas vue2 uses a default export of the Vue constructor, which is what your original post was using, e.g., new Vue() Your webpack.mix.js config should also indicate the Vue version you want to use so it can pull in the necessary dependencies for the respective Vue version.

Anthonysb's avatar

@apex1 that was helpful, ok so I see what you mean now, use createApp instead of new Vue to init vue, I changed it but in web pack I have never specified a version of vue I just assumed .vue() would just pull in what I had package.json

can you show me how do do that?

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .vue()
    .postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
]);

and here is my updated app.js

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/inertia-vue3'

createInertiaApp({
  resolve: name => require(`./pages/${name}`),
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})
apex1's avatar

@Anthonysb I believe mix will default to vue2 so you need to use .vue({ version: 3 }) and of course recompile with npm run dev.

Anthonysb's avatar

@apex1 ok my watcher now says its compiled and build success for but I get an error in the javascript saying

Unhandled Promise Rejection: Error: Cannot find module './pages/home' but I have the path correct I'm not sure why it says it can't find it?

Anthonysb's avatar

@apex1 I finally got it, I didn't need to specify pages in my controller and that's why I couldn't find it

Anthonysb's avatar

@apex1 thanks I just need a little advice and direction, I have only been learning for about 6months by myself and really want to learn vue and inertia to up my abilities, I'm not very good yet but I can manage simple to intermediate Laravel projects, I just to want to limit what kind of work I can do cause I only know one framework.

Please or to participate in this conversation.