Günther Debrauwer - February 12th, 2023

Using Laravel Valet proxy command with Laravel Sail and Vite

With the release of Laravel’s Vite plugin, we started switching from Laravel Mix to Vite at work. But we ran into a problem because we use Laravel Sail and Laravel Valet’s proxy command: the assets would not load when running Vite in development mode. This blog post will show you how to get Laravel Valet’s proxy command and Laravel Sail and Laravel Vite Plugin to all work nicely together.

Laravel Valet’s proxy command

When you just use Laravel Sail to run your project, you have to remember the app port to go to the correct localhost url. To make your life a bit easier, you can use the proxy command of Laravel Valet. Using the command, we can define a custom .test domain that will proxy urls of that domain to the localhost url with the correct port. You can also use the flag --secure when creating the proxy. This flag will create a TLS certificate for the domain so your app url uses https instead of http.

valet proxy myprojectname http://localhost:XXXX --secure

When we have created this proxy, we must change the app url in our local environment file. The proxy exists outside the PHP docker container, so Laravel does not know the custom base url without explicitly setting it in the environment file.

APP_URL=https://myprojectname.test
ASSET_URL="${APP_URL}"

Because we are using a proxy, we also need to update the TrustProxies middleware of our application so it trusts any proxy. To ensure that it only trusts all proxies when the application is running locally, we check the app environment.

class TrustProxies extends Middleware
{
    protected function proxies()
    {
        if (App::environment('local')) {
            return '*';
        }

        return $this->proxies;
    }
}

When you now go to https://myprojectname.test, you will see your Laravel application! But there is a problem. When you start Vite in development mode by running sail npm run dev, you will see that the assets do not load.

Configure Laravel Vite Plugin

The reason the assets are not loaded when running Vite’s development server, is that Vite does not know our proxied url. This can be fixed by configuring the host in vite.config.js file.

export default defineConfig({
    // ...
    server: {
        host: 'myprojectname.test',
        hmr: {
            host: 'myprojectname.test',
        },
    },
});

If you now run sail npm run dev, you will see that it can still not load the assets. The base url is already correct, but it can not load the assets because of an issue with the TLS certificate of the .test domain. This is caused by the fact that the TLS certificate exists outside the docker container. To fix that, we will have to make 2 changes to our setup.

Firstly, we have to change our docker-compose.yml file. In the volumes section of our PHP container, we have to add the .crt and .key files of the certificate. These files are located in Valet’s global configuration folder. When we restart the PHP docker container, those files will be available in the container.

version: '3'
services:
	myprojectname.test
		# ...
		volumes:
			- '.:/var/www/html:delegated'
			- '${HOME}/.config/valet/Certificates/myprojectname.test.key:/var/www/Certificates/myprojectname.test.key'
			- '${HOME}/.config/valet/Certificates/myprojectname.test.crt:/var/www/Certificates/myprojectname.test.crt'

Now the certificate files exist in the docker container, but Vite does not know yet where it can find them. We have to update the Vite config file and point Vite to the location of the certificate files inside the docker container.

import fs from 'fs';

export default defineConfig({
    // ...
    server: {
        host: 'myprojectname.test',
        hmr: {
            host: 'myprojectname.test',
        },
        https: {
            key: fs.readFileSync('/var/www/Certificates/myprojectname.test.key'),
            cert: fs.readFileSync('/var/www/Certificates/myprojectname.test.crt'),
        },
    },
});

When you now start Vite’s development server, you can go to https://myprojectname.test and your assets will be loaded correctly. You can start developing the UI of your Laravel application!