Pixelairport's avatar

Mixed Content Problem with Lando, Vite and NPM

I have to ask now, because this is a problem I try to solve for long time now. I switched from homestead to docker/lando and now I get an error for my page:

Mixed Content: The page at 'https://breezer.lndo.site/' was loaded over HTTPS, but requested an insecure script 'http://breezer.lndo.site:3009/resources/js/Pages/Welcome.vue'. This request has been blocked; the content must be served over HTTPS.

I cannot say what I already tried, but I feel I tried everything. I setup ASSET_URL in env file, I tried to force Https in provider like a lot of people say. But nothing works. This is what i now have:

// Lando File
name: breezer
recipe: laravel
config:
  webroot: ./public
  php: 8.2
services:
  node:
    type: node:18
    scanner: false
    ports:
      - 3013:3009
    build:
      - npm install
  pma:
    type: phpmyadmin
    hosts:
      - database
  mailhog:
    type: mailhog
    portforward: true
proxy:
  pma:
    - breezer.pma.lndo.site
  mailhog:
    - breezer.mh.lndo.site
tooling:
  npm:
    service: node
    cmd: npm
  dev:
    service: node
    cmd: npm run dev
  build:
    service: node
    cmd: npm run build
// Vite File
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,
                },
            },
        }),
    ],
    server: {
        https: true,
        host: true,
        port: 3009,
        hmr: {host: 'breezer.lndo.site', protocol: 'ws'},
    },
});

Does anyone maybe see what the problem is? Because, when I call https://breezer.lndo.site the site works, but vite tries always to call the scripts without https. Only http.

0 likes
5 replies
LaryAI's avatar
Level 58

The issue you're encountering is due to Vite's development server serving assets over HTTP while your main site is being served over HTTPS. This results in mixed content errors because modern browsers block HTTP content on HTTPS pages for security reasons.

To resolve this, you need to ensure that Vite's server also uses HTTPS. You've already configured Vite to use HTTPS in your Vite config file, but you need to make sure that the HMR (Hot Module Replacement) connection is also using a secure protocol.

Here's what you can do:

  1. Update the hmr option in your Vite configuration to use wss (WebSocket Secure) instead of ws. This will ensure that the WebSocket connection for HMR is also secure.
// Vite File
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,
                },
            },
        }),
    ],
    server: {
        https: true,
        host: true,
        port: 3009,
        hmr: {
            host: 'breezer.lndo.site',
            protocol: 'wss', // Change 'ws' to 'wss'
        },
    },
});
  1. Ensure that your Lando configuration forwards the correct HTTPS port for the Vite server. You've mapped port 3013 to 3009, but you need to make sure that the 3013 port is also served over HTTPS.

  2. If you're using a self-signed certificate for local development, you may need to configure your browser to trust the certificate, or you may need to add an exception for your local development domain.

  3. Make sure that any environment variables or configurations that reference asset URLs are using https as the protocol.

After making these changes, restart your Lando services and Vite server. Your assets should now be served over HTTPS, and the mixed content issue should be resolved. If you continue to experience issues, double-check your Lando proxy settings and ensure that all services are correctly configured to use HTTPS.

Pixelairport's avatar

Ok. That with 3013 and 3009 I have to say... I dont really know how to set this up. What should I do there? Is that the problem? Can somebody help? I switched from ws to wss. But my code still use http instead of https.

martinbean's avatar

@Pixelairport You most likely need to configure your TrustProxies middleware.

The nuclear option is:

class TrustProxies extends Middleware
{
    protected $proxies = '*';
    protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
}

This will then allow your Laravel application to correctly detect it should generate HTTPS URLs when behind a proxy or load balancer.

Pixelairport's avatar

Thx @martinbean I tested it, but it not works. The problem is not, that laravel refuse the connection. The problem seems to be, that vite is using http://breezer.lndo.site instead of https://breezer.lndo.site. I dont know how to say vite to use https. I thought I alread say it with https: true.

In my blade I use

@vite(['resources/js/app.js', "resources/js/Pages/{$page['component']}.vue"])

I is generated automatically. I try to use breeze with inertia. But the scripts are called without https. Just http. How can I tell vite to use https.

Pixelairport's avatar
Pixelairport
OP
Best Answer
Level 12

It works... :) ... in my vite server object I needed to setup the https key and cert which seems is created by lando. For look at this there is a command called lando ssh. This is my vite:

server: {
        https: {
            cert: fs.readFileSync('/lando/certs/appserver.breezer.crt'),
            key: fs.readFileSync('/lando/certs/appserver.breezer.key'),
        },
        host: true,
        port: 3009,
        hmr: {host: 'breezer.lndo.site', protocol: 'wss'},
    },

I set the path to the files, set also wss instead of ws and in my env i set ASSET_URL. Now it works :)

Please or to participate in this conversation.