I have a Laravel project using Inertia with React that I'm attempting to deploy on an Azure VM to use as a staging environment.
The issue I'm running into seems to be a common one, but none of the given solutions have any impact on Vite's behavior. When I try to access my project over https, I am able connect to the server but Vite has no clue where to go -- not only does it try to fetch content over http rather than https, but it also tries to get the content from an invalid address (http://[::]:5173). I am able to get this to change if I edit the public/hot file, but the server is then unable to resolve the files required: Uncaught TypeError: Failed to resolve module specifier "https://[<server IP>]:5173/@react-refresh". Relative references must start with either "/", "./", or "../".
I start Vite on my staging server with vite --host --cors --mode stage and receive this output once started:
VITE v6.2.5 stage ready in 216 ms
➜ Local: http://localhost:5173/
➜ Network: http://<Azure Private IP>:5173/
➜ press h + enter to show help
LARAVEL v11.44.0 plugin v1.2.0
➜ APP_URL: https://<App URL>
Following the code snippet here, and the information from the official Laravel docs my vite.config.js file looks like this:
import {defineConfig, loadEnv} from 'vite';
import laravel from 'laravel-vite-plugin';
import basicSsl from '@vitejs/plugin-basic-ssl';
import react from '@vitejs/plugin-react';
import fs from 'fs';
export default defineConfig((command, mode) => {
if(mode === 'stage'){
const env = loadEnv('', process.cwd(), '');
return {
server:{
host: env.VITE_ASSET_HOST,
port: env.VITE_ASSET_PORT,
strictPort: true,
hmr:{
host: true,
port: env.VITE_ASSET_PORT
},
https: {
key: fs.readFileSync(env.VITE_PRIVKEY_PATH),
cert: fs.readFileSync(env.VITE_CERT_PATH),
}
},
resolve: name =>{
const pages = import.meta.glob(`./Pages/${name}.tsx`)
return pages[`./Pages/${name}.tsx`]()
},
plugins: [
laravel({
input: 'resources/js/app.tsx',
ssr: 'resources/js/ssr.tsx',
refresh: true,
}),
react(),
basicSsl(),
],
}
} else {
return {
resolve: name =>{
const pages = import.meta.glob(`./Pages/$(name}.tsx`)
return pages[`./Pages/$(name}.tsx`]()
},
plugins: [
laravel({
input: 'resources/js/app.tsx',
ssr: 'resources/js/ssr.tsx',
refresh: true,
}),
react(),
],
}
}
});
While my .env file looks like this:
APP_NAME="<app name>"
APP_ENV=stage
APP_KEY=<...>
APP_DEBUG=true
APP_URL=<server url>
API_URL=<server url>/api
ASSET_URL=<server url>
VITE_APP_NAME="<app name>"
VITE_APP_URL="<server url>"
VITE_DEV_SERVER_URL="<server url>"
VITE_ASSET_HOST="<server url>"
VITE_ASSET_PORT=5173
VITE_PRIVKEY_PATH="/etc/letsencrypt/live/<server url>/privkey.pem"
VITE_CERT_PATH="/etc/letsencrypt/live/<server url>/cert.pem"
[ . . . ]
I've found that if I change my startup script to vite --host <server url> -- mode stage, Vite will exit with the error address not available. This is true whether or not I specify the server host in my vite.config.js file, and also if I do not define the server.hmr.host option.
Adding the Azure Private IP and the public IP to my Trusted Proxies has not changed anything, and neither has setting the ASSET_URL env variable.
My SSL certificate paths point to symbolic links, so I tried pointing them at the original files in case the symbolic links were an issue.
I've tried running my vite command with sudo and as the root user to make sure it wasn't a permissions issue.
I've also tried using the server IP address instead of the server URL as suggested in this StackOverflow page, and have gone through all of the steps in this StackOverflow answer with no changes to Vite's behavior.
Any help or point in the right direction would be welcome! I'm new to Laravel and Vite, so I'm sure there's something I've missed but I haven't been able to identify it.