Laravel Vite: Assets blocked/Mixed Content issues in production environment - laravel

I'm hosting my App on an EC2-instance behind an Elastic Load Balancer which manages my SSL-Certificate. On this EC2-Instance my nginx-configuration is redirecting all http-Requests to https.
I recently switched to Vite which caused me a lot of trouble. When I push my app to the server after calling npm run build my assets are blocked. In the browser console I get:
Mixed Content: The page at 'example.com' was loaded over HTTPS, but requested an insecure ...
My Setup:
vite.config.js
export default defineConfig({
server: {
host: 'localhost',
},
plugins: [
laravel([
'resources/assets/sass/app.sass',
// etc...
]),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
Setting "https: true" in the server-block didn't help me.
.env
APP_ENV=production
APP_URL=https://example.com
ASSET_URL=https://example.com
In my blade template I'm using the Vite-directive:
#vite('resources/assets/sass/app.sass')
I tried the following solutions:
Setting $proxies = '*' in TrustProxies.php, which doesn't have any effect.
Setting URL::forceScheme('https'); in AppServiceProvider.php, which will load the assets but lead to a lot of other issues.
Somehow the #vite-directive is not resolving my assets as secure assets. With Laravel Mix I could just call secure_asset.
How can I fix this?

In the end I used the TrustedProxies-middleware. However back then I forgot to register it as global middleware.

import fs from 'fs';
const host = 'example.com';
server: {
host,
hmr: {host},
https: {
key: fs.readFileSync(`ssl-path`),
cert: fs.readFileSync(`ssl-cert-path`),
},
},
you should add this to vite.config.js file along with ASSET_URL to your .env file

Related

why don't images with absolute url work in my css (laravel / vite)?

I configured project with laravel 9 and everything works. Then I moved the layout and everything is fine too.
When I make a resource build, the site works correctly.
B0ut when vite runs server (0.0.0.0), then all the images that are registered in css do not work.
All images are in the public folder. And I move them over is not an option for me.
csss code:
background-image: url('/img/home/sweets-one.png');
{my_local}/img/home/sweets-one.png - 200
http://0.0.0.0:3000/img/home/sweets-one.png - 404
vite config:
export default defineConfig({
server: {
host: '0.0.0.0',
port: 3000,
open: false,
},
plugins: [
vue(),
laravel({
input: [
// css
'resources/scss/app.scss',
],
refresh: true,
}),
],
});
how can I fix it?
So, If we user docker and local domain with custom port, you need configure Vite also.
For example:
My project use docker and works on the domain: mysite.loc:8080
So, Vite should be configured like this:
export default defineConfig({
server: {
host: 'mysite.loc',
port: 8080,
open: false,
},
plugins: [
vue(),
laravel({
input: [
// css
'resources/scss/app.scss',
],
refresh: true,
}),
],
});

Laravel 9 + vue.js 3 error, after moving public folder to public_html on webHostingServer

Hi guys i had laravel 9 with Vue.js 3 installed locally. They both worked fine.
But than i oploaded on a webHosting server and moved public folder to public_html folder.
I set in appserverProviders register follofing code:
$this->app->bind('path.public', function() {
return "myPath/public_html";
});
in vite.config i have like this:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
server: {
hmr: {
host: 'localhost',
},
},
plugins: [
vue(),
laravel({
input: [
'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
],
});
The error looks llike this:
client.ts:78 WebSocket connection to 'wss://127.0.0.1:5173/' failed:
setupWebSocket # client.ts:78
(anonym) # client.ts:68
client.ts:78 WebSocket connection to 'wss://127.0.0.1:5173/' failed:
setupWebSocket # client.ts:78
fallback # client.ts:43
(anonym) # client.ts:99
client.ts:48 [vite] failed to connect to websocket.
your current setup:
(browser) 127.0.0.1:5173/ <--[HTTP]--> 127.0.0.1:5173/ (server)
(browser) 127.0.0.1:5173/ <--[WebSocket (failing)]--> 127.0.0.1:5173/ (server)
Check out your Vite / network configuration and https://vitejs.dev/config/server-
options.html#server-hmr .
what is to be done to solve this error and use vue.js 3 with laravel 9.
please dont hesitate to ask further questions if you got. thanks

Default Laravel + Vite configuration throws WebSocket connection to failed:

So Laravel decided to innovate once again and fix what was not broken, so Mix is gone and now default asset bundling goes with Vite.
I'm following the absolute default in their documentation to a bunch of front-end bugs and finally only several remained:
I use Laragon with SSL.
I haven't configured anything additional and my vite.config.js looks like this:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
When I run npm run dev and visit the Laragon domain I get the following in the console:
client.ts:78 WebSocket connection to 'wss://127.0.0.1:5173/' failed.
client.ts:48 [vite] failed to connect to websocket.
your current setup:
(browser) 127.0.0.1:5173/ <--[HTTP]--> 127.0.0.1:5173/ (server)
(browser) 127.0.0.1:5173/ <--[WebSocket (failing)]--> 127.0.0.1:5173/ (server)
Check out your Vite / network configuration and https://vitejs.dev/config/server-options.html#server-hmr .
I guess I need to configure my actual domain somewhere? I tried doing that in a server object in the config, but it didn't help those errors.
PS: Now in my vue files I need to import including the .vue extension e.g. import Button from '#/Components/Button.vue' is there any way I can ommit the .vue like it was with Laravel Mix?
I haven't use laragon before, but if you have a custom domain, eg, like
http://cutom-domain.test, you need to tell vite to use the certificate like so;
In your vite.config.js, add a server key with the following configuration
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
import fs from 'fs';
import { homedir } from 'os';
import { resolve } from 'path';
// Ignore the protocol on the host, ie do not put "http"
const host = 'cutom-domain.test';
const viteServerConfig = 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),
},
}
}
export default defineConfig({
server: viteServerConfig(host),
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
Credit to this blogpost that explains more - Making Vite and Valet play nice together
I don't know if it's still relevant, but looking in the source code of laravel-vite-plugin I found a way to solve this problem in a very simple way, without even changing the vite.config.js file.
Put these two variables in the .env file and set them with full path to .key and .crt files on your system:
VITE_DEV_SERVER_KEY='C:/laragon/etc/ssl/laragon.key'
VITE_DEV_SERVER_CERT='C:/laragon/etc/ssl/laragon.crt'
Do not change anything on vite.config.js file. Here is my (fresh install of laravel + jetstream w/ inertia and --ssr):
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
ssr: 'resources/js/ssr.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
And that's it. Run npm run dev and Vite will "magically" start a development server with https on.
VITE v4.0.4 ready in 1248 ms
➜ Local: https://laravel.test:5173/
➜ Network: https://192.168.1.2:5173/
➜ press h to show help
LARAVEL v9.48.0 plugin v0.7.3
➜ APP_URL: https://laravel.test/
Even though the configuration present in the official documentation also works, this way is much simpler, and the host, key and cert variables are not defined in the file, but they are dynamic reflecting the dev environment.
Hope this helps someone.
Here is the source where I found this, and you can also inspect in node_modules\laravel-vite-plugin\dist\index.js of your project.
When I do npm run build instead of regular npm run dev, the problem is gone. I guess, build mechanism is different for prod, so there is no WSS related errors in console.
So, in other words, perform a production Vite build and deploy it (if you are testing on a remote project).

Laravel Vite Can't change base url for ping pong

I am using my own nginx server to run laravel application. The problem that I cannot change base_url/__vite_ping. It tries to request https://server.test/__vite_ping rather than https://localhost:3000/__vite_ping. Here is my vite.config.js
import {defineConfig} from 'vite';
import fs from 'fs';
import laravel from 'laravel-vite-plugin';
const ASSET_URL = process.env.ASSET_URL || '';
export default defineConfig({
base: `${ASSET_URL}`,
server: {
https: {
key: fs.readFileSync('resources/ssl/localhost.key'),
cert: fs.readFileSync('resources/ssl/localhost.crt'),
},
host: 'localhost',
},
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],
});
When I run vite -d, the config base does not change its always remains with value '/', is there a way to change base_url ?
The issue is closed, as somehow it got resolved by itself, I had problem with one of my memory so it could have caused some bugs I could not explain.

Rewrites not working on Vercel (in production) NextJS

I have been trying to get Rewrites working in NextJS for my API Paths. It was to avoid CORS issues.
I followed the solution from: NextJs CORS issue.
It is working on localhost but does not work in a production environment (I was deploying on Vercel itself).
I basically tried with all the types of rewrites:
async rewrites() {
return {
beforeFiles: [
{
source: "/api/:path*",
destination: `https://example.com/api/v1/:path*`,
basePath: false,
},
],
afterFiles: [
{
source: "/api/:path*",
destination: `https://example.com/api/v1/:path*`,
basePath: false,
},
],
fallback: [
{
source: "/api/:path*",
destination: `https://example.com/api/v1/:path*`,
basePath: false,
},
],
};
},
This rewrite works on localhost but on production, the rewrite stops working and the API calls go to /api/:path* itself.
The /api path is reserved for their Serverless Functions. Changing the source path to something else would resolve the issue.

Resources