Laravel 9 (with Vite) and Vue 3 integration [For Metronic versions before v8.1.6]

Requirement

  • Metronic version before v8.1.6
  • PHP 8.1.9+
  • Composer 2.4.1+
  • Node 16.16.0+


  • Create a new Laravel 9 project


    1. In the beginning, we need to create a Laravel+Vue project (in this example, we will create a project named vue_laravel) by running a command.

      composer create-project --prefer-dist laravel/laravel vue_laravel


    2. Navigate to the newly created folder with the command below.

      cd vue_laravel


    Install dependencies


    1. Metronic 8 Vue theme already contains almost all required dependencies for this integration, to get started we can copy a list of dependencies from package.json in Vue and place them into vue_laravel/package.json.

      Also, include "devDependencies" listed below.

      "array-sort": "^1.0.0",
      "sass": "^1.44.0",
      "sass-loader": "^12.4.0",
      "vuex-module-decorators": "^1.2.0"

    2. Let's install vue vite plugin.

      npm install --save-dev @vitejs/plugin-vue

    3. Install all dependencies by running the following command.
      npm install


    Prepare vue files and theme resources


    1. From public folder in vue project copy and paste the files and folder listed below.

      > fonticon
      > media
      > favicon.ico
      > splash-screen.css


    2. Copy vue variables from .env file in vue project and paste them to vue_laravel/.env and vue_laravel/.env.example files.

    3. Copy src folder and paste it into vue_laravel/resources/ts.

    4. Create ts folder inside vue_laravel/resources/ts and inside this folder create file app.ts.

    5. The main entry point of the vue project is main.ts, we need to import it in app.ts, copy import below and paste it to your vue_laravel/resources/ts/app.ts.
      import "./src/main";


    6. For Vite we need to do some global replacements.

      In file vue_laravel/resources/ts/src/App.vue remove ~ aliase from style imports.

      @import "bootstrap-icons/font/bootstrap-icons.css";
      @import "apexcharts/dist/apexcharts.css";
      @import "quill/dist/quill.snow.css";
      @import "animate.css";
      @import "sweetalert2/dist/sweetalert2.css";
      @import "nouislider/distribute/nouislider.css";
      @import "@fortawesome/fontawesome-free/css/all.min.css";
      @import "socicon/css/socicon.css";
      @import "line-awesome/dist/line-awesome/css/line-awesome.css";
      @import "dropzone/dist/dropzone.css";
      @import "@vueform/multiselect/themes/default.css";
      @import "prism-themes/themes/prism-shades-of-purple.css";
      @import "element-plus/dist/index.css";

      Globally replace VUE_APP environment variable names to VITE_APP and replace usage from process.env to import.meta.env.


    Configure vite.config.js


    1. Copy vite.js configuration below and paste it to your vue_laravel/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: [
      vue({
      template: {
      transformAssetUrls: {
      includeAbsolute: false,
      },
      },
      }),
      laravel([
      'resources/css/app.css',
      'resources/ts/app.ts',
      ]),
      ],
      resolve: {
      alias:{
      '@/': path.join(__dirname, '/resources/ts/src/'),
      '~': path.join(__dirname, '/node_modules/'),
      },
      },
      build: {
      chunkSizeWarningLimit: 1600,
      },
      });



    Prepare app.blade.php


    1. Now we can add a new file inside resources/views. Let's call it app.blade.php

    2. Copy the code below and paste it to your app.blade.php.
      <!DOCTYPE html>
      <html>

      <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Metronic Vue and Laravel Starterkit</title>
      <link rel="icon" href="./favicon.ico">
      <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700">
      <link rel="stylesheet" href="./fonticon/fonticon.css">
      <link rel="stylesheet" href="./splash-screen.css">

      @vite('resources/css/app.css')
      </head>

      <body class="page-loading">
      <!--begin::Theme mode setup on page load-->
      <script>
      if (document.documentElement) {
      var defaultThemeMode = "system";

      var name = document.body.getAttribute("data-kt-name");
      var themeMode = localStorage.getItem("kt_" + (name ? name + "_" : "") + "theme_mode_value");

      if (themeMode === null) {
      if (defaultThemeMode === "system") {
      themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
      } else {
      themeMode = defaultThemeMode;
      }
      }
      document.documentElement.setAttribute("data-theme", themeMode);
      }
      </script>
      <!--end::Theme mode setup on page load-->


      <div id="app"></div>
      <!--begin::Loading markup-->
      <div class="splash-screen">
      <img src="./media/logos/default-small.svg" alt="Metronic logo" />
      <span>Loading ...</span>
      </div>
      <!--end::Loading markup-->

      @vite('resources/ts/app.ts')
      </body>
      </html>



    3. Now we can add a new route to file routes/web.php.
      Route::get('/', function () {
      return view('app');
      });


    Run project


    1. Firstly we need to build the client, let's run the command.
      npm run dev


    2. This command will build our js/css files and will listen for changes in our vue folder to hot-reload them. Keep client-server running.

    3. In another tab navigate the project and run laravel project with the command below.
      php artisan serve


    4. Wait for the app to display that it is running on http://127.0.0.1:8000 then open this URL in your browser.

    Text formatting options
    Submit
    Here's a how to add some HTML formatting to your comment:
    • <pre></pre> for JS codes block
    • <pre lang="html"></pre> for HTML code block
    • <pre lang="scss"></pre> for SCSS code block
    • <pre lang="php"></pre> for PHP code block
    • <code></code> for single line of code
    • <strong></strong> to make things bold
    • <em></em> to emphasize
    • <ul><li></li></ul>  to make list
    • <ol><li></li></ol>  to make ordered list
    • <h3></h3> to make headings
    • <a></a> for links
    • <img> to paste in an image
    • <blockquote></blockquote> to quote somebody
    • happy  :)
    • shocked  :|
    • sad  :(

    Replies (22)

    Great post! Thank you happy

    Is it possible that there is a step that is missing here? I followed these directions exactly. When I go to the URL, I just get a logo and text that says loading. The URL now says: http://127.0.0.1:8000/#/sign-in but I can't get anywhere else. It didn't seem like vite was creating the assets but I am not sure. This was extremely helpful though. Thank you.

    Hi,

    Do you have any errors in your browser console?

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    There are no errors.

    I was able to get it working. In the code you posted for the app.blade.php file, the div is missing the id tag so the page was not loading. Do we need to do anything additional to get the api working? In previous documentation for vue + laravel integration it seems like localhost:8000/api should allow you to access the api, but in my console after signing in I am seeing a 404 error: POST http://127.0.0.1:8000/api/login 404 (Not Found)

    wondering if i am missing something else? I did remove the # from the URLs so not sure if that is causing the issue.

    Hi,

    Thank you for your feedback.

    We already updated code preview for app.blade.php.

    You should be able to access an API without making any changes, if you are using our ApiService.ts to make an HTTP request then you just need to update VITE_API_URL in .env file. Also, make sure that you have registered all endpoints in your routes/api.php correctly https://laravel.com/docs/9.x/routing.

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    Sorry but I don't understand the "replace use of process.env to import.meta.env" part, could you be please more specific. Thanks

    Hi,

    By default in our theme, we are using process.env.VARIABLE_NAME to access .env variables, but this will not work for Vite, one of the options to use .env variables in Vite project is import.meta.env.VARIABLE_NAME.

    For this integration, you need to replace all process.env, you can use global replace functionality of your code editor to replace all process.env to import.meta.env.

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    hii i'am following ur step above but i got an error like this
    vite version: vite/3.1.8
    OS:Linux Mint 20.3 (una)
    Laravel: 9.19


    [sass] ENOENT: no such file or directory, open '/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/bootstrap/scss/functions'

    17 │ @import "~bootstrap/scss/functions";
    │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

    resources/ts/src/assets/sass/_init.scss 17:9 @import
    resources/ts/src/assets/sass/plugins.scss 10:9 @import
    resources/ts/src/App.vue 18:9 root stylesheet
    3:42:48 PM [vite] Internal server error: [sass] ENOENT: no such file or directory, open '/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/bootstrap/scss/functions'

    17 │ @import "~bootstrap/scss/functions";
    │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

    resources/ts/src/assets/sass/_init.scss 17:9 @import
    resources/ts/src/assets/sass/plugins.scss 10:9 @import
    resources/ts/src/App.vue 18:9 root stylesheet
    Plugin: vite:css
    File: /home/cmh-arv/Projects/laravel/ayaklinik/resources/ts/src/assets/sass/_init.scss
    Error: ENOENT: no such file or directory, open '/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/bootstrap/scss/functions'

    17 │ @import "~bootstrap/scss/functions";
    │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

    resources/ts/src/assets/sass/_init.scss 17:9 @import
    resources/ts/src/assets/sass/plugins.scss 10:9 @import
    resources/ts/src/App.vue 18:9 root stylesheet
    at Object.wrapException (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:1247:17)
    at NodeImporter._handleImportResult$4 (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:85811:17)
    at /home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:85750:50
    at _wrapJsFunctionForAsync_closure.$protected (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:3738:15)
    at _wrapJsFunctionForAsync_closure.call$2 (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:28402:12)
    at _awaitOnObject_closure.call$1 (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:28390:32)
    at Object._rootRunUnary (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:4113:18)
    at StaticClosure. (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:99102:16)
    at _CustomZone.runUnary$2$2 (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:29799:39)
    at _Future__propagateToListeners_handleValueCallback.call$0 (/home/cmh-arv/Projects/laravel/ayaklinik/node_modules/sass/sass.dart.js:28871:51)

    Hi,

    Have you included the following alias in your vite.config.js?

    { find: '~bootstrap', replacement: path.resolve(__dirname,'node_modules/bootstrap')},

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    hello i have error when i try to build for prod using "npm build"

    [vite]: Rollup failed to resolve import "/media/auth/404-error.png" from "resources/ts/src/views/etc/Error404.vue".
    This is most likely unintended because it can break your application at runtime.
    If you do want to externalize this module explicitly add it to
    `build.rollupOptions.external`

    can you share vite.config.js for build.rollupOptions.external wildcard for all external media/*?

    Hi,

    Sorry for the late reply.

    By default, in our theme path is "media/auth/404-error.png", could you please try to use a path without "/"?

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    I have the same issue
    when I run npm build I get this error:
    Unable to locate file in Vite manifest: resources/ts/app.ts.

    if I change the path to resources/js/app.js in the app.blade file the dashboard freeze on splash screen and nothing else happen

    Hi Mohamed,

    We just updated vite.config.js to fix some issues for the production build. Could you please rerun the build command with the updated config?

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    What version of metronic was this article written about? I am trying it with Metronic v8.1.5 and nothing works.

    Hi,

    The post should work for Metronic v8.1.5. Do you have any errors?

    In Metornic v8.1.6 we migrated to Create-Vue app and started to use Vite, so this tutorial might not be valid anymore. We will revise it and fix it as soon as possible.

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    I get many errors, I dont know if its on my end but let me detail them to you.

    First of all for step 2)

    I get error:

    npm ERR! code ERESOLVE
    npm ERR! ERESOLVE unable to resolve dependency tree
    npm ERR!
    npm ERR! While resolving: undefined@undefined
    npm ERR! Found: @popperjs/core@2.11.5
    npm ERR! node_modules/@popperjs/core
    npm ERR! @popperjs/core@"2.11.5" from the root project
    npm ERR!
    npm ERR! Could not resolve dependency:
    npm ERR! peer @popperjs/core@"^2.11.6" from bootstrap@5.2.2
    npm ERR! node_modules/bootstrap
    npm ERR! bootstrap@"5.2.2" from the root project
    npm ERR!
    npm ERR! Fix the upstream dependency conflict, or retry
    npm ERR! this command with --force or --legacy-peer-deps
    npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

    Thats the first error, I can get past this step by adding --force.

    Same thing with npm install, I have to add --force.

    In between step 4 and step 5 Im not sure if theres a step mission or if Im doing something wrong but there is no "src/App.vue" in the ts folder that we just created so Im assuming we are taking the "src" folder from the metronic package and copying it to the newly created "ts" folder?

    Then after running php artisan serve I get

    [plugin:vite:css] [sass] Can't find stylesheet to import.

    17 │ @import "~bootstrap/scss/functions";
    │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

    resources/ts/src/assets/sass/_init.scss 17:9 @import
    resources/ts/src/assets/sass/plugins.scss 10:9 @import
    resources/ts/src/App.vue 18:9 root stylesheet
    /Applications/XAMPP/xamppfiles/htdocs/vue_laravel/resources/ts/src/App.vue:55:9

    can you update this with the new version, v8.1.6?

    hi,

    i got this error :
    [plugin:vite:import-analysis] Failed to resolve import "./src/main" from "resources\ts\app.ts". Does the file exist?

    can u help me?

    Hi,

    Could you please specify which Metronic version are you using?

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    sorry, i m using v8.1.6, do u have tutorial for this version?

    Hi,

    We just added an updated post for Metronic v8.1.6+.
    https://devs.keenthemes.com/question/laravel-9-vue-with-vite-integration-metronic-v816

    Regards,
    Lauris Stepanovs,
    Keenthemes Support Team

    Text formatting options
    Submit
    Here's a how to add some HTML formatting to your comment:
    • <pre></pre> for JS codes block
    • <pre lang="html"></pre> for HTML code block
    • <pre lang="scss"></pre> for SCSS code block
    • <pre lang="php"></pre> for PHP code block
    • <code></code> for single line of code
    • <strong></strong> to make things bold
    • <em></em> to emphasize
    • <ul><li></li></ul>  to make list
    • <ol><li></li></ol>  to make ordered list
    • <h3></h3> to make headings
    • <a></a> for links
    • <img> to paste in an image
    • <blockquote></blockquote> to quote somebody
    • happy  :)
    • shocked  :|
    • sad  :(
    Text formatting options
    Submit
    Here's a how to add some HTML formatting to your comment:
    • <pre></pre> for JS codes block
    • <pre lang="html"></pre> for HTML code block
    • <pre lang="scss"></pre> for SCSS code block
    • <pre lang="php"></pre> for PHP code block
    • <code></code> for single line of code
    • <strong></strong> to make things bold
    • <em></em> to emphasize
    • <ul><li></li></ul>  to make list
    • <ol><li></li></ol>  to make ordered list
    • <h3></h3> to make headings
    • <a></a> for links
    • <img> to paste in an image
    • <blockquote></blockquote> to quote somebody
    • happy  :)
    • shocked  :|
    • sad  :(