From e083a22bffe52e008eedadf1f92df5998c9d8583 Mon Sep 17 00:00:00 2001 From: masterdev Date: Tue, 16 Jun 2026 23:12:00 +0100 Subject: [PATCH] Support secure same-origin API URLs --- README.md | 20 ++++++++++++++++++++ frontend/src/lib/api.ts | 27 +++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 63fc23a..b9fde1b 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,26 @@ If the browser shows a CORS error, make sure the exact frontend origin is in FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site ``` +If the frontend is served over HTTPS, the WebSocket URL must use `wss://`, not +`ws://`. Browsers block insecure WebSockets from secure pages. Recommended +same-domain reverse proxy variables: + +```env +FRONTEND_ORIGIN=https://plasttrack.sable.ynsdev.site +FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site +VITE_API_BASE_URL=https://plasttrack.sable.ynsdev.site +VITE_WS_URL=wss://plasttrack.sable.ynsdev.site/ws/dashboard +VITE_ALLOWED_HOSTS=plasttrack.sable.ynsdev.site,localhost,127.0.0.1 +``` + +The reverse proxy must route: + +```text +/api/* -> backend:8000 +/ws/dashboard -> backend:8000 +/* -> frontend:5173 +``` + ### 3. Deploy Click `Deploy the stack`. diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 052c4d3..b161399 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -1,5 +1,28 @@ -export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8000"; -export const WS_URL = import.meta.env.VITE_WS_URL ?? "ws://localhost:8000/ws/dashboard"; +function resolveApiBaseUrl() { + const configuredUrl = import.meta.env.VITE_API_BASE_URL; + if (configuredUrl) { + return configuredUrl; + } + if (typeof window === "undefined") { + return "http://localhost:8000"; + } + return window.location.origin; +} + +function resolveWsUrl() { + const configuredUrl = import.meta.env.VITE_WS_URL; + if (configuredUrl) { + return configuredUrl; + } + if (typeof window === "undefined") { + return "ws://localhost:8000/ws/dashboard"; + } + const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; + return `${protocol}//${window.location.host}/ws/dashboard`; +} + +export const API_BASE_URL = resolveApiBaseUrl(); +export const WS_URL = resolveWsUrl(); export async function fetchJson(path: string, init?: RequestInit): Promise { const response = await fetch(`${API_BASE_URL}${path}`, {