Laravel 9 (with Vite) and Vue 3 integration

Requirement

  • 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. Create ts folder inside vue_laravel/resources/ts and inside this folder create file app.ts.

    4. 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";


    5. 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 path from 'path'
      import { defineConfig } from 'vite';
      import vue from '@vitejs/plugin-vue'
      import laravel from 'laravel-vite-plugin';

      export default defineConfig({
      resolve: {
      alias: [
      { find: '~bootstrap', replacement: path.resolve(__dirname,'node_modules/bootstrap')},
      { find: '@', replacement: path.resolve(__dirname,'resources/ts/src/') }
      ]
      },
      plugins: [
      vue(),
      laravel({
      input: ['resources/css/app.css', 'resources/js/app.js'],
      refresh: true,
      }),
      ],
      });



    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 (6)

    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

    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  :(