Making Vite and Valet play nice together
Yesterday, the Laravel team launched the official vite-plugin. From now on, Vite will be the standard build tool for Laravel. The main benefits are vastly improved build times and a more straightforward API. Want to know more about it? Head over to the official docs. There's also a migration guide to go from Mix to Vite.
When I followed that guide to upgrade the freek.dev codebase from Mix to Vite , npm dev
could successfully start-up Vite, but in the browser the JS / CSS did not load. Let's review how I could fix that.
For local development, I rely on Valet to run sites. For each site, I usually run valet secure
so the site loads over HTTPS. And that is what is causing problems. By default, Vite will use the https://localhost:3000
domain to serve assets. But by default, your browser doesn't trust HTTPS from localhost
as there is no matching certificate.
Tim MacDonald was so friendly to point me to the official docs that contain a solution. You have to add this bit of configuration to your Vite config file.
export default defineConfig({
// ...
server: {
https: true,
host: 'localhost',
},
});
And then, you need to go to https://localhost:3000 in your browser. You'll get a warning that there is no certificate, and you have to accept the security warning there.
That will work, but there's another way which doesn't involve having to click away from a security warning. You can configure Vite in such a way that it will use the certificates that Valet generates.
Here's what the vite.config.js
file looks like for freek.dev.
import fs from 'fs';
import laravel from 'laravel-vite-plugin'
import {defineConfig} from 'vite'
import {homedir} from 'os'
import {resolve} from 'path'
let host = 'freek.dev.test'
export default defineConfig({
plugins: [
laravel([
'resources/js/app.js',
]),
],
server: detectServerConfig(host),
})
function detectServerConfig(host) {
let keyPath = resolve(homedir(), `.config/valet/Certificates/${host}.key`)
let certificatePath = resolve(homedir(), `.config/valet/Certificates/${host}.crt`)
if (!fs.existsSync(keyPath)) {
return {}
}
if (!fs.existsSync(certificatePath)) {
return {}
}
return {
hmr: {host},
host,
https: {
key: fs.readFileSync(keyPath),
cert: fs.readFileSync(certificatePath),
},
}
}
This code will check if the certificates generated by Valet exist, and if they do, use them. Those certificates do not exist in production, and the default server configuration will be used.
This is slightly more complex than the official suggestion solution, but it has the benefit that you don't have to click away from that security warning. I can promise you that on a new computer, you'll forget that you have to do that and lose some time.
The Vite and vite-plugin themselves are great, by the way. It results in dramatically increased build times for my projects.
Want some more Vite goodness? Check out my other blog post on how to configure Vite to automatically reload your browser when you save a Blade file.
There are probably more ways to fix this problem. Let me (and my other readers) know your solution in the comments below.
What about using Valet proxies? https://laravel.com/docs/9.x/valet#proxying-services
Thx so much Freek, just installed a new laravel app, and this Vite stuff was driving me nuts ! You can go on vacation and relax now ;)
It took me a while to get vite working with laravel homestead on windows. A part of the code you posted helped me a lot.
I will share all my current vite configuration for laravel homestead in windows environment.
My setup still doesn't work with latest laravel :|
Am I doing anything wrong? Please help
Please take a look at my last reply on this post. That should work with latest laravel-version.
If you can do without the hot reload feature, doing an
npm run build
is a much simpler solution
To use APP_URL from .env-file as host to prevent setting up the host in multiple files you can use vites loadEnv-method
This has been incorporated in the Laravel Vite plugin via a
valetTls
option, see the documentation: Working With A Secure Development Server