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

Moseskamau338's avatar

Vue-cli integration to inertiajs (Nightmare!)

It's been like 2 days now since I began integrating my newly acquired Vuejs dashboard template (Metronic from Theme forest) to Laravel 8 Inertiajs installation. The assets migrate well, but I have not been able to solve one notorious npm error. I have googled the whole earth but nothing yet:

Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Failed to find 'init'
  in [
    /root/code/fort/app/resources/js/Layouts,
        /root/code/fort/app/resources/js/assets/sass
  ]
    at /root/code/fort/app/node_modules/postcss-import/lib/resolve-id.js:35:13
    at async Promise.all (index 0)

 @ ./node_modules/style-loader!./node_modules/css-loader/dist/cjs.js??ref--8-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-2!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/Layouts/DashLayout.vue?vue&type=style&index=0&lang=css& 2:14-321
 @ ./resources/js/Layouts/DashLayout.vue?vue&type=style&index=0&lang=css&
 @ ./resources/js/Layouts/DashLayout.vue
 @ ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/Pages/Dashboard2.vue?vue&type=script&lang=js&
 @ ./resources/js/Pages/Dashboard2.vue?vue&type=script&lang=js&
 @ ./resources/js/Pages/Dashboard2.vue
 @ ./resources/js/Pages sync ^\.\/.*$
 @ ./resources/js/app.js
 @ multi ./resources/js/app.js ./resources/sass/canvas-ui.scss ./resources/js/assets/sass/style.vue.scss ./resources/css/app.css

Am not even sure what code to share here because its just a big mess. Does anyone have a guide to do what am trying to achieve here (Migrate from Vue-cli app to Inertiajs)?

Am really stranded!

//Pages/Dashboard2.vue (New dashboard)
<template>
  <dash-layout>
    <!--begin::Dashboard-->
    <div class="row">
      <div class="col-xxl-4">
        <MixedWidget1></MixedWidget1>
      </div>
      <div class="col-xxl-4">
        <ListWidget9></ListWidget9>
      </div>
      <div class="col-xxl-4">
        <StatsWidget7></StatsWidget7>
        <StatsWidget12></StatsWidget12>
      </div>

      <div class="col-xxl-4 order-1 order-xxl-1">
        <ListWidget1></ListWidget1>
      </div>
      <div class="col-xxl-8 order-2 order-xxl-1">
        <AdvancedTableWidget2></AdvancedTableWidget2>
      </div>

      <div class="col-xxl-4 order-1 order-xxl-2">
        <ListWidget3></ListWidget3>
      </div>
      <div class="col-xxl-4 order-1 order-xxl-2">
        <ListWidget4></ListWidget4>
      </div>
      <div class="col-lg-12 col-xxl-4 order-1 order-xxl-2">
        <ListWidget8></ListWidget8>
      </div>

      <div class="col-xxl-4 order-1 order-xxl-2">
        <StatsWidget13></StatsWidget13>
      </div>
      <div class="col-xxl-8 order-1 order-xxl-2">
        <AdvancedTableWidget3></AdvancedTableWidget3>
      </div>
    </div>
    <!--end::Dashboard-->
  </dash-layout>
</template>

<script>
import DashLayout from '@/Layouts/DashLayout'
import { SET_BREADCRUMB } from "@/core/services/store/breadcrumbs.module";
import AdvancedTableWidget2 from "@/view/content/widgets/advance-table/Widget2.vue";
import AdvancedTableWidget3 from "@/view/content/widgets/advance-table/Widget3.vue";
import MixedWidget1 from "@/view/content/widgets/mixed/Widget1.vue";
import ListWidget1 from "@/view/content/widgets/list/Widget1.vue";
import ListWidget3 from "@/view/content/widgets/list/Widget3.vue";
import ListWidget4 from "@/view/content/widgets/list/Widget4.vue";
import ListWidget8 from "@/view/content/widgets/list/Widget8.vue";
import ListWidget9 from "@/view/content/widgets/list/Widget9.vue";
import StatsWidget7 from "@/view/content/widgets/stats/Widget7.vue";
import StatsWidget12 from "@/view/content/widgets/stats/Widget12.vue";
import StatsWidget13 from "@/view/content/widgets/stats/Widget13.vue";

export default {
  name: "dashboard",
  components: {
    DashLayout,
    AdvancedTableWidget2,
    AdvancedTableWidget3,
    MixedWidget1,
    ListWidget1,
    ListWidget3,
    ListWidget4,
    ListWidget8,
    ListWidget9,
    StatsWidget7,
    StatsWidget12,
    StatsWidget13
  },
  mounted() {
    this.$store.dispatch(SET_BREADCRUMB, [{ title: "Dashboard" }]);
  },
  methods: {
    setActiveTab1(event) {
      this.tabIndex = this.setActiveTab(event);
    },
    setActiveTab2(event) {
      this.tabIndex2 = this.setActiveTab(event);
    },
    /**
     * Set current active on click
     * @param event
     */
    setActiveTab(event) {
      // get all tab links
      const tab = event.target.closest('[role="tablist"]');
      const links = tab.querySelectorAll(".nav-link");
      // remove active tab links
      for (let i = 0; i < links.length; i++) {
        links[i].classList.remove("active");
      }

      // set current active tab
      event.target.classList.add("active");

      // set clicked tab index to bootstrap tab
      return parseInt(event.target.getAttribute("data-tab"));
    }
  }
};
</script>
DashLayout.vue
<template>
  <div class="d-flex flex-column flex-root">
    <!-- begin:: Header Mobile -->
    <KTHeaderMobile></KTHeaderMobile>
    <!-- end:: Header Mobile -->

    <Loader v-if="loaderEnabled" v-bind:logo="loaderLogo"></Loader>

    <!-- begin::Body -->
    <div class="d-flex flex-row flex-column-fluid page">
      <!-- begin:: Aside Left -->
      <KTAside v-if="asideEnabled"></KTAside>
      <!-- end:: Aside Left -->

      <div id="kt_wrapper" class="d-flex flex-column flex-row-fluid wrapper">
        <!-- begin:: Header -->
        <KTHeader></KTHeader>
        <!-- end:: Header -->

        <!-- begin:: Content -->
        <div
          id="kt_content"
          class="content d-flex flex-column flex-column-fluid"
        >
          <!-- begin:: Content Head -->

          <!-- begin:: Content Head -->
          <KTSubheader
            v-if="subheaderDisplay"
            v-bind:breadcrumbs="breadcrumbs"
            v-bind:title="pageTitle"
          />
          <!-- end:: Content Head -->

          <!-- begin:: Content Body -->
          <div class="d-flex flex-column-fluid">
            <div
              :class="{
                'container-fluid': contentFluid,
                container: !contentFluid
              }"
            >
              <transition name="fade-in-up">
                <router-view />
              </transition>
            </div>
          </div>
        </div>
        <KTFooter></KTFooter>
      </div>
    </div>
    <KTStickyToolbar v-if="toolbarDisplay"></KTStickyToolbar>
    <KTScrollTop></KTScrollTop>
  </div>
</template>

<script>

import { OVERRIDE_LAYOUT_CONFIG } from "@/core/services/store/config.module";
import { mapGetters } from "vuex";
import KTAside from "@/view/layout/aside/Aside.vue";
import KTHeader from "@/view/layout/header/Header.vue";
import KTHeaderMobile from "@/view/layout/header/HeaderMobile.vue";
import KTFooter from "@/view/layout/footer/Footer.vue";
import HtmlClass from "@/core/services/htmlclass.service";
import KTSubheader from "@/view/layout/subheader/Subheader.vue";
import KTStickyToolbar from "@/view/layout/extras/StickyToolbar.vue";
import KTScrollTop from "@/view/layout/extras/ScrollTop";
import Loader from "@/view/content/Loader.vue";
import {
  ADD_BODY_CLASSNAME,
  REMOVE_BODY_CLASSNAME
} from "@/core/services/store/htmlclass.module.js";

export default {
  name: "F.O.R.T Dashboard",
  components: {
    KTAside,
    KTHeader,
    KTHeaderMobile,
    KTFooter,
    KTSubheader,
    KTStickyToolbar,
    KTScrollTop,
    Loader
  },
  beforeMount() {
    // show page loading
    this.$store.dispatch(ADD_BODY_CLASSNAME, "page-loading");

    // initialize html element classes
    HtmlClass.init(this.layoutConfig());
  },
  mounted() {
     /**
     * this is to override the layout config using saved data from localStorage
     * remove this to use config only from static json (@/core/config/layout.config.json)
     */
    this.$store.dispatch(OVERRIDE_LAYOUT_CONFIG);

    // Simulate the delay page loading
    setTimeout(() => {
      // Remove page loader after some time
      this.$store.dispatch(REMOVE_BODY_CLASSNAME, "page-loading");
    }, 2000);
  },
  methods: {},
  computed: {
    ...mapGetters([
      "breadcrumbs",
      "pageTitle",
      "layoutConfig"
    ]),

    /**
     * Check if the page loader is enabled
     * @returns {boolean}
     */
    loaderEnabled() {
      return !/false/.test(this.layoutConfig("loader.type"));
    },

    /**
     * Check if container width is fluid
     * @returns {boolean}
     */
    contentFluid() {
      return this.layoutConfig("content.width") === "fluid";
    },

    /**
     * Page loader logo image using require() function
     * @returns {string}
     */
    loaderLogo() {
      return process.env.BASE_URL + this.layoutConfig("loader.logo");
    },

    /**
     * Check if the left aside menu is enabled
     * @returns {boolean}
     */
    asideEnabled() {
      return !!this.layoutConfig("aside.self.display");
    },

    /**
     * Set the right toolbar display
     * @returns {boolean}
     */
    toolbarDisplay() {
      // return !!this.layoutConfig("toolbar.display");
      return false;
    },

    /**
     * Set the subheader display
     * @returns {boolean}
     */
    subheaderDisplay() {
      return !!this.layoutConfig("subheader.display");
    }
  }
};
</script>
<style>
@import url("bootstrap-vue/dist/bootstrap-vue.css");
@import url("perfect-scrollbar/css/perfect-scrollbar.css");
@import url("socicon/css/socicon.css");
@import url("animate.css");
@import url("@fortawesome/fontawesome-free/css/all.css");
@import url("line-awesome/dist/line-awesome/css/line-awesome.css");
@import url("../assets/plugins/flaticon/flaticon.css");
@import url("../assets/plugins/flaticon2/flaticon.css");
@import url("../assets/plugins/keenthemes-icons/font/ki.css");

/*// Main demo style scss*/
/*@import url("assets/css/style.vue.rtl";)*/
@import url("../assets/sass/style.vue.scss");
</style>
0 likes
4 replies
Moseskamau338's avatar
Moseskamau338
OP
Best Answer
Level 5

I ended up using an HTML version of the design to bring in Inertia. Looks like it impossible to introduce Inertia at a later period of the project progress

1 like
Ömer Ergün's avatar

I also used HTML version. The problem i faced is the scripts are not loading after login redirect of fortify.

<script type="application/javascript" src="{{ asset('assets/plugins/global/plugins.bundle.js') }}"></script>
<script type="application/javascript" src="{{ asset('assets/jas/scripts.bundle.js') }}"></script>

Did you also faced this problem? Somehow external scripts are not loading without refresing page.

AmarBunty's avatar

Can anyone pls share tutorial / documentation to integrate metronic 8 with VUE3 and ineriajs. git repo with Metronic Inertia Vue boilerplate most welcome..

Thanks

Moseskamau338's avatar

@AmarBunty I suffered terrible things trying that....If I were you I would check to see if the owners of Metronic are planning to upgrade Vue anytime.... the main issue to my inderstanding has been that Bootstrap 4 Vue is still using Vue2

Please or to participate in this conversation.