Laravel 9 (with Vite) and Vue 3 integration [For Metronic v8.1.6+]
Requirement
Create a new Laravel 9 project
- 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
- Navigate to the newly created folder with the command below.
cd vue_laravel
Install dependencies
- 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 intovue_laravel/package.json
.Also, include "devDependencies" listed below.
"array-sort": "^1.0.0",
"sass": "^1.44.0",
"sass-loader": "^12.4.0", - Let's install vue vite plugin.
npm install --save-dev @vitejs/plugin-vue
- Install all dependencies by running the following command.
npm install
Prepare vue files and theme resources
- Copy
public/media
folder from Vue project intovue_laravel/public/
folder. - From
public
folder in vue project copy files listed below and paste them intopublic
folder in Laravel folder.
> favicon.ico
> splash-screen.css - Copy vite variables from
.env
file in vue project and paste them tovue_laravel/.env
andvue_laravel/.env.example
files. - Create ts folder inside
vue_laravel/resources/ts
and inside this folder create fileapp.ts
. - Copy
src
folder and paste it intovue_laravel/resources/ts
. - 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";
Configure vite.config.js
- 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({
base: "/",
plugins: [
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
laravel({
input: ["resources/css/app.css", "resources/js/app.js"],
refresh: true,
}),
],
resolve: {
alias: {
"@/": path.join(__dirname, "/resources/ts/src/"),
"~": path.join(__dirname, "/node_modules/"),
},
},
build: {
chunkSizeWarningLimit: 1600,
},
});
Prepare app.blade.php
- Now we can add a new file inside
resources/views
. Let's call itapp.blade.php
- 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="./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> - Now we can add a new route to file
routes/web.php
.Route::get('/', function () {
return view('app');
});
Run project
- Firstly we need to build the client, let's run the command.
npm run dev
- 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.
- In another tab navigate the project and run laravel project with the command below.
php artisan serve
- Wait for the app to display that it is running on http://127.0.0.1:8000 then open this URL in your browser.
Replies (8)
Hi,
Thanks for the update.
I've a few questions about the vite config.
1. Why is base: "/assets" ? Probably when you npm run dev it will become http://127.0.0.1:8000/assets.
2. Why is inpunt resources/js/app.js and not resources/ts/app.ts
3. Can you also describe how to prepare the other files like .eslintrc.cjs and tsconfig.json?
Update
I've followed the steps and when I run 'npm run dev', I'm getting the following error:
failed to load config from ./vite.config.js
error when starting dev server:
Error: Cannot find module 'laravel-vite-plugin'
Require stack:
- ./vite.config.js
- ./rijsoftware/node_modules/vite/dist/node/chunks/dep-5605cfa4.js
Hi,
- If you want you can avoid this by removing the base path property from vite.config.js and then updating paths in file vue_laravel/resources/ts/src/core/helpers/assets.ts. For getIllustrationsPath and getAssetPath you will need to remove
/
before media in a path otherwise you will have two slashes before the path and non of the media files will be found. - It was the default configuration code if you are planning to handle all your frontend with vue you can just remove this plugin from the list.
app.ts file is specified inside your view:
@vite('resources/ts/app.ts')
- I will add this to our backlog. For now to add eslint you can refer to https://gist.github.com/EmadAdly/b356690a4cb3b9a79d6757d5ebd6c93c
This package should be in the list of devDependencies by default, you should keep default devDependencies and add those I described in the post.
Regards,
Lauris Stepanovs,
Keenthemes Support Team
Well, I followed the steps and changed resources/js/app.js to resources/ts/app.ts. I had to install laravel-vite-plugin too. After doing this I run the command
npm run build-only
because npm run build wasn't working
transforming (1) resources/ts/app.tsERROR: "type-check" exited with 1.
Finally it's working, but with a lot of console errors, because the assets are not found. e.g.:
- http://127.0.0.1:8000/assets/assets/LayoutService.73065d7f.js net::ERR_ABORTED 404 (Not Found)
- http://127.0.0.1:8000/assets/assets/SignIn.37bee318.js net::ERR_ABORTED 404 (Not Found)
- http://127.0.0.1:8000/assets/assets/assets.1bc0fb6f.js net::ERR_ABORTED 404 (Not Found)
- http://127.0.0.1:8000/assets/assets/sweetalert2.all.31f6258e.js net::ERR_ABORTED 404 (Not Found)
and many more...
Is it working on your side? Can you maybe create a video tutorial or just a simple starter kit with laravel vue? Chatting is taking to much time . I've waited 1 week for the doc update, but it's still not complete and not working!!!
During the testing, we didn't have these errors.
Did you include all of the devDependencies?
"devDependencies": {
"@vitejs/plugin-vue": "^4.0.0",
"array-sort": "^1.0.0",
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.2",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"sass": "^1.44.0",
"sass-loader": "^12.4.0",
"vite": "^4.0.0"
}
Regards,
Lauris Stepanovs,
Keenthemes Support Team
Yes, those packages are included. I'll write down step by step what I did:
1. Create a new Laravel 9 project
2. Install dependencies
3. Prepare vue files and theme resources
Copied public/media to public/assets/ and public (for to be sure). So now I have public/media and public/assets/media
4. Configure vite.config.js
export default defineConfig({
plugins: [
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
laravel({
input: ["resources/css/app.css", "resources/ts/app.ts"],
refresh: true,
}),
],
resolve: {
alias: {
"@/": path.join(__dirname, "/resources/ts/src/"),
"~": path.join(__dirname, "/node_modules/"),
},
},
build: {
chunkSizeWarningLimit: 3000,
},
});
5. Prepare app.blade.php
6. Remove / from vue_laravel/resources/ts/src/core/helpers/assets.ts.
I have also added BASE_URL to .env; BASE_URL=BASE_URL=https://demo:8890
export const getIllustrationsPath = (illustrationName: string): string => {
const extension = illustrationName.substring(
illustrationName.lastIndexOf("."),
illustrationName.length
);
const illustration =
useThemeStore().mode == "dark"
? `${illustrationName.substring(
0,
illustrationName.lastIndexOf(".")
)}-dark`
: illustrationName.substring(0, illustrationName.lastIndexOf("."));
return (
import.meta.env.BASE_URL +
`media/illustrations/${illustrationsSet.value}/${illustration}${extension}`
);
};export const getAssetPath = (path: string): string => {
return import.meta.env.BASE_URL + path;
};
6. Run project
npm run dev
VITE v3.2.5 ready in 1084 ms ➜ Local: http://127.0.0.1:5173/
➜ Network: use --host to expose
LARAVEL v9.45.1 plugin v0.7.3
➜ APP_URL: https://demo:8890
php artisan serve
INFO Server running on [http://127.0.0.1:8000]. Press Ctrl+C to stop the server
When I go to http://127.0.0.1:8000 or https://demo:8890 app is running, but media or icons are not loaded. I see many errors, e.g.:
- GET https://media/misc/auth-screens.png net::ERR_NAME_NOT_RESOLVED
- GET https://media/stock/600x400/img-20.jpg net::ERR_NAME_NOT_RESOLVED
Maybe it helps; I am working Mac with Mamp PRO.
Hi,
You need to remove BASE_URL
property from your .env
file. You overrided BASE_URL property, which refers to public
folder by default.
Regards,
Lauris Stepanovs,
Keenthemes Support Team
Hello,
I have tried this solution with Metronic version 8.1.7 but it does not work. I have several errors with the imports, it seems that the alias does not pass? I don't know what is happening.
Can you help me to install Metronic 8.1.7 in laravel 9 with fast and Vue?
Thanks in advance, pray
Hi,
Could you please send us your error messages?
Regards,
Lauris Stepanovs,
Keenthemes Support Team