diff --git a/src/Client/Shared/JsonWire.fs b/src/Client/Shared/JsonWire.fs index 358d415..fa64c06 100644 --- a/src/Client/Shared/JsonWire.fs +++ b/src/Client/Shared/JsonWire.fs @@ -10,7 +10,13 @@ open Fable.Core open Fable.Core.JsInterop open Domain -let private serverUrl = "http://localhost:5144" +// Relative on purpose — the server is always reached through whatever's +// serving this page under `/api/*`: the client's own nginx in Docker +// (see Client/nginx.conf), Vite's dev-server proxy (vite.config.js) for +// `npm run dev`, or the host reverse proxy in production. This also means +// the browser never makes a cross-origin request, so CORS never enters +// into it for any of these setups. +let private serverUrl = "" [] let hasKey (_o: obj) (_key: string) : bool = jsNative diff --git a/src/Client/nginx.conf b/src/Client/nginx.conf index 73ade1e..9a5e186 100644 --- a/src/Client/nginx.conf +++ b/src/Client/nginx.conf @@ -2,6 +2,17 @@ server { listen 80; root /usr/share/nginx/html; + # No trailing slash on proxy_pass here — the full matched URI (including + # the /api/ prefix) is forwarded unchanged, matching Giraffe's route + # definitions in Server/Routes.fs, which all start with /api/. + location /api/ { + proxy_pass http://server:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location / { try_files $uri $uri/ /index.html; } diff --git a/vite.config.js b/vite.config.js index d5deae5..0363bc1 100644 --- a/vite.config.js +++ b/vite.config.js @@ -4,5 +4,11 @@ export default defineConfig({ root: "src/Client", server: { port: 5173, + proxy: { + "/api": { + target: "http://localhost:5144", + changeOrigin: true, + }, + }, }, });