Using Laravel 9 with Breeze with DDEV and Vite
When trying to use a fresh Laravel 9 installation with breeze, you’ll encounter the problem that your browser won’t be able to load and hot-replace the assets compiled by vite.
If you face the problem, follow these steps to get your HMR working:
Extend DDEV web-service configuration
Create a new file in you DDEV project’s .ddev
folder, called docker-compose.vite.yaml
and add the following config:
version: '3.6'
services:
web:
expose:
- "5173"
environment:
HTTP_EXPOSE: ${DDEV_ROUTER_HTTP_PORT}:80,${DDEV_MAILHOG_PORT}:8025,5174:5173
HTTPS_EXPOSE: ${DDEV_ROUTER_HTTPS_PORT}:80,${DDEV_MAILHOG_HTTPS_PORT}:8025,5173:5173
5173
is the internal port of the vite http-server. TheHTTP_EXPOSE
is required, otherwise ddev-router won’t be able to start up. The exposed port (5174
, left hand side) in theHTTP_EXPOSE
list must be different from the exposed port in theHTTPS_EXPOSE
list.
Restart your DDEV instance, then continue to next step.
You should now be able to open both urls
https://yourproject.ddev.site:5173
and
http://yourproject.ddev.site:5174
Both will display a “502: Unresponsive/broken ddev back-end site”-error for now.
Update vite.config.js
Update the server section of your vite config like this:
//...
server : {
hmr:{
host: process.env.DDEV_HOSTNAME,
protocol : 'wss'
}
},
//...
You’ll notice that the protocol is set to wss. The reason is the way that the actual asset-URL that’s written into your document. It will only use a https-protocol-part if the protocol is set to wss
because it is assumed that you use a non-ssl environment on the special localhost
-hostname.
Alternative: Customize Illuminate\Foundation\Vite’s HMR URL
If you’re not comfortable with setting the protocol to wss or simply want another domain than DDEV_HOSTNAME for whatever reason, I’ve made a small middleware that lets you override the URL that’s passed to the document for asset inclusion:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CustomHMRHotFile
{
/**
* Allow for different HMR URLs, regardless of what vite-plugin generates.
*
* @see https://mtillmann.blog/posts/using-laravel-9-breeze-with-ddev-and-vite.html
* @see https://github.com/laravel/vite-plugin/issues/156
*
* Install:
* - copy this file to app/Http/Middleware/CustomHMRHotFile.php
* - add `\App\Http\Middleware\CustomHMRHotFile::class` to app/Http/Kernel.php: Kernel::$middleware[]
*
*
* @param \Illuminate\Http\Request $request
* @param \Closure\Illuminate\Http\Request: (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (is_file(public_path('hot'))) {
$originalContent = file_get_contents(public_path('hot'));
$customContent = str_replace('http://', 'https://', $originalContent);
if ($originalContent !== $customContent) {
file_put_contents(public_path('hot'), $customContent);
}
}
return $next($request);
}
}
Starting vite the correct way
When you start npm run dev
, the server’s output will suggest
Network: use --host to expose
This is will not properly expose your vite dev server. Run this command to actually expose your vite dev server:
npm run dev -- --host
# or from your host shell:
ddev exec npm run dev -- --host
The output should indicate that your vite dev server now listens on other interfaces than only localhost.
Now you should be able to navigate to
https://yourproject.ddev.site/login
and see assets (app.css, app.js, @vite/client) being loaded from
https://yourproject.ddev.site:5173
Running vite on ddev start
Add the following to .ddev/config.yaml
to have vite start with the web container:
hooks:
post-start:
- exec: "npm run dev -- --host"
This post was originally published on medium.com on 26-10-2022
Clicking this button loads third-party content from utteranc.es and github.com