Closed bakerkretzmar closed 2 years ago
This is probably not Valet related. I have the same issue serving the local dev site with Lando (Docker).
This is only an issue with Vite 2.x, the ping works differently in Vite 3.x which will be released in the upcoming days/weeks (see https://github.com/vitejs/vite/pull/6819). I'm not even sure if this is fixable on our side because the ping uses the base
URL, which must be /
.
That's good to know 👍🏻 I think the socket connection is also failing initially, which is a bigger problem right? It must have something to do with using HTTPS locally but I'm not sure if the fix would be something in Vite, this plugin, Valet, or somewhere else.
Yes, you're getting the ping loop because Vite couldn't connect in the first place - I think the Vite plugin should do that automatically, but for now maybe try configuring server.https
yourself?
I'll try that tomorrow, I don't recall what needs to be setup on the top of my head
Thanks for reporting this, @bakerkretzmar.
The __vite_ping
issue is known and will be fixed in Vite 3 as mentioned by @innocenzi.
I don't have a Mac (and therefore Valet) to reproduce the socket issue, but I'll check it out with @timacdonald's help tomorrow.
Hey, so I just tried and at least the following server
configuration is needed for https
to work and the websocket to connect:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
server: {
https: true,
hmr: {
host: 'localhost',
}
}
});
The host
is necessary because otherwise the websocket will try to connect using location.hostname
.
@jessarcher I think the hmr
host should always be set, and https
should be auto-determined depending on APP_URL
, like vite-plugin-laravel
does.
I haven't looked into why ws://browser-hostname
works and wss://browser-hostname
doesn't, but setting the host
to the dev server's host works in both cases.
@innocenzi thanks a ton, I'll add that config! It sounds like that wouldn't be super hard to figure out and configure automatically inside this plugin, hopefully that can be added 👍🏻
@jessarcher
I don't have a Mac (and therefore Valet) to reproduce the socket issue
Just pointing out here that this isn't valet specific, it's anything that allows you to have a valid https local dev setup that's not on https://localhost. If you're going to work on this (which I'd totally get if we just skip it until Vite3 and maybe pin this issue instead) I'd suggest checking out Lando as that runs on Windows, Linux, and Mac and takes about 5 minutes to setup :)
I agree that setting server.https
to true makes sense when the APP_URL
starts with https:
. This works around the Vite client defaulting to wss
when visiting a https
site.
It's also possible to force the Vite client to connect over ws
by setting server.hmr.protocol
, however browsers understandably don't want to connect to ws
when visiting a https
site.
As for server.hmr.host
, I think this is more complicated. The bigger issue is the use of self-signed certificates.
When you browse to your Valet site over https
site (e.g. https://valet-vite.test) with a self-signed certificate, you need to accept the certificate, however, this only accepts the Valet certificate, and only for the hostname and port you've visited (i.e. valet-vite.test:443
).
It does not accept the Vite certificate.
The only way I can see to accept the Vite certificate is to browse to the https
version of the wss
URL and accept it there. E.g. https://valet-vite:3000
, https://localhost:3000
, or https://127.0.0.1:3000
. I don't think it matters much what server.hmr.host
is set to, as long as you accept the certificate at whichever host the browser connects to. The only benefit I can see to setting it to localhost
is that it will probably work for any Valet site once you've done it once.
I haven't looked into why
ws://browser-hostname
works andwss://browser-hostname
doesn't, but setting thehost
to the dev server's host works in both cases.
I suspect this would work if you browsed to https://browser-hostname:3000
and accepted the certificate. I'm also assuming wss://localhost:3000
works for you because you've previously accepted Vite's certificate at https://localhost:3000
.
It is possible to configure Vite to use Valet's key and certificate, however, this does not solve the issue because the certificate needs to be accepted separately for each port (i.e. 443 and 3000). This is not a problem in the normal Vite world because they always browse to port 3000.
You are absolutely correct it's more complicated than it first seems. Our personal setup is using lando so the SSL cert is actually valid (*.lndo.site is a real domain registered that points to 127.0.0.1) and we use mkcert to generate our localhost valid certificate and pass that through to vite instead of letting it generate its own.
I was considering whether we could setup vite to proxy through to the laravel site so we could manage it the same way they do in the vite world, but that wouldn't work for subdomain routed apps.
I feel like the only suitable 'solution' to this issue is going t o be education on typical debugging steps given the range of setups people may have.
I feel like the only suitable 'solution' to this issue is going t o be education on typical debugging steps given the range of setups people may have.
This is what I'm leaning towards as well. I still think it's worth setting server.https
when APP_URL
starts with https:
so at least all the developer needs to do is get the certificate accepted.
We could also consider adding some output to the console when this is set, with a link to the vite dev server URL so they can easily click it and accept the certificate.
It's also worth noting that this issue exists with Mix as well.
I don't think we should detect this from the APP_URL
. The APP_URL
is not directly related to the URL that the site is being viewed at...
APP_URL=http://foo.bar
composer create-project laravel/laravel my-app
cd my-app
valet link
open http://my-app.test
# or...
php -S 0.0.0.0:8998
open http://0.0.0.0:8998
# or...
php artisan serve
open http://127.0.0.1:8000
# or...
sail up -d
open http://localhost
None of these are related in anyway to the APP_URL, so I don't think auto-detecting is a good idea.
The APP_URL may be https and the site may not be and vice-versa.
That's a good point @timacdonald.
Also, if no one provides a server.host
setting, the hot file will get https://127.0.0.1:3000
(auto-detected from the Vite dev server) while the Vite client will auto-detect wss://valet-vite.test:3000
from the browser, meaning that the user would need to accept two certificates, in addition to the one they already have to accept at https://valet-vite.test
.
Until we can think of something more reliable, I think we'll just document adding this to vite.config.js
:
server: {
https: true,
host: 'localhost',
}
And then to make sure to visit the following link to accept the certificate:
This has been added to the docs PR at https://github.com/laravel/docs/pull/7984/commits/168786d84d7aba43ea7785ecaa5a7f1748d2740d
Going to close this issue for now. Thanks again for all your help everyone!
@timacdonald I still think APP_URL
is a good heuristic - it should correspond to most defaults, and one can override the server
configuration anyway.
I can confirm we still need to accept the certificate, but we indeed need to do that only once. Laravel Vite auto-detects Valet and Laragon certificates and uses them, which reduces the configuration needed by the user to get https
working.
I don't think it's bad to have good defaults that would work in a lot of cases, even if not all of them.
@jessarcher thanks a lot! Glad this is documented now, and I think accepting the additional certificate is a good workaround.
I still think it makes sense to use APP_URL
to do even more automatically when possible. This won't cover absolutely every use case, but I think it actually is—usually—directly related to the URL that the site is being viewed at.
I'm not shutting down the idea at all, just sharing a perspective. Will chat to Jess more about it and maybe have a play with the idea a bit more.
Thanks for all the discussion folks ❤️
I had the same problem, I fixed it by adding the key and certificate as I already did with laravel mix.
I created an article to show this working.
👉 https://dev.to/paulocastellano/how-to-make-vite-valet-and-ssl-works-together-5hbb
I had the same problem, I fixed it by adding the key and certificate as I already did with laravel mix.
I created an article to show this working.
👉 https://dev.to/paulocastellano/how-to-make-vite-valet-and-ssl-works-together-5hbb
While this works, when testing npm run build
it essentially breaks as we have explicitly set the domain. I get the error Unable to locate file in Vite manifest: resources/css/app.css.
when using @vite on the header.
Hopefully there's a cleaner way to make this work with Valet. Seems a bit of extra fluff to start new projects compared to Mix.
Description:
When serving a local development site, e.g.
valet-vite.test
, using Valet, after the site is secured with HTTPS usingvalet secure
the connection towss://valet-vite.test:3000
fails, and all the pings tohttps://valet-vite.test/__vite_ping
404.The errors look like this (screenshot is Firefox, errors are the same in Chrome).
Steps To Reproduce:
composer create-project laravel/laravel:9.x-dev valet-vite && cd valet-vite
valet link valet-vite && valet secure
@vite('resources/js/app.js')
toresources/views/welcome.blade.php
APP_URL
tohttps://valet-vite.test
npm install && npm run dev