From 87a7a31ecef664f2377fe9a81ae04b4b09d46f87 Mon Sep 17 00:00:00 2001 From: Till JS Date: Fri, 8 May 2026 22:03:35 +0200 Subject: [PATCH] fix(web): SvelteKit-env via \$env/dynamic/public statt import.meta.env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: Browser-Client requested localhost:3081 statt cardecky-api.mana.how nach Login. Ursache: API_BASE und authBaseUrl() lasen die Variable über import.meta.env.PUBLIC_*, was unter SvelteKit nicht zuverlässig inlined wird (Vite-direct, ohne SvelteKit-Wrapper-Hook). Fix: \$env/dynamic/public liest die env zur Runtime aus den Node- Server-Variablen (adapter-node) — Browser bekommt sie über den SSR-Init-Snapshot. Damit muss die Variable nur als runtime-env am Container hängen, nicht als Build-Arg. docker-compose.production.yml: PUBLIC_CARDS_API_URL und PUBLIC_MANA_AUTH_URL aus build.args nach environment verschoben. Build-Pipeline: cards-web muss neu gebaut werden, sonst greift der Wechsel von static→dynamic env nicht. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/src/lib/api/client.ts | 11 ++++++++--- apps/web/src/lib/auth/dev-stub.svelte.ts | 8 ++++---- infrastructure/docker-compose.production.yml | 6 +++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/apps/web/src/lib/api/client.ts b/apps/web/src/lib/api/client.ts index bccf580..0cc871f 100644 --- a/apps/web/src/lib/api/client.ts +++ b/apps/web/src/lib/api/client.ts @@ -10,11 +10,16 @@ */ import { devUser } from '$lib/auth/dev-stub.svelte.ts'; +import { env as publicEnv } from '$env/dynamic/public'; +// `$env/dynamic/public` liest die env zur Runtime aus den ENV-Vars +// des Node-Servers (adapter-node). Im Browser kommt der Wert aus dem +// vom Server gerenderten Init-Snapshot, daher gleicher Pfad für SSR +// und Client. Falls nichts gesetzt → localhost:3081 (Dev-Default). export const API_BASE = (() => { - if (typeof window !== 'undefined') { - return import.meta.env.PUBLIC_CARDS_API_URL ?? 'http://localhost:3081'; - } + const fromPublic = publicEnv.PUBLIC_CARDS_API_URL; + if (fromPublic) return fromPublic; + if (typeof window !== 'undefined') return 'http://localhost:3081'; return process.env.CARDS_API_URL ?? 'http://localhost:3081'; })(); diff --git a/apps/web/src/lib/auth/dev-stub.svelte.ts b/apps/web/src/lib/auth/dev-stub.svelte.ts index 6df061b..57820c8 100644 --- a/apps/web/src/lib/auth/dev-stub.svelte.ts +++ b/apps/web/src/lib/auth/dev-stub.svelte.ts @@ -50,11 +50,11 @@ function isExpired(claims: JwtClaims): boolean { return claims.exp * 1000 < Date.now(); } +// SvelteKit-konformer ENV-Zugriff (siehe client.ts für Begründung). +import { env as publicEnv } from '$env/dynamic/public'; + function authBaseUrl(): string { - if (typeof import.meta !== 'undefined' && import.meta.env?.PUBLIC_MANA_AUTH_URL) { - return import.meta.env.PUBLIC_MANA_AUTH_URL; - } - return 'https://auth.mana.how'; + return publicEnv.PUBLIC_MANA_AUTH_URL ?? 'https://auth.mana.how'; } class Session { diff --git a/infrastructure/docker-compose.production.yml b/infrastructure/docker-compose.production.yml index 33986cc..9966957 100644 --- a/infrastructure/docker-compose.production.yml +++ b/infrastructure/docker-compose.production.yml @@ -103,11 +103,15 @@ services: dockerfile: apps/web/Dockerfile args: NPM_AUTH_TOKEN: ${NPM_AUTH_TOKEN:?missing NPM_AUTH_TOKEN} - PUBLIC_CARDS_API_URL: https://cardecky-api.mana.how restart: unless-stopped depends_on: - cards-api environment: + # SvelteKit `$env/dynamic/public` liest zur Runtime — daher + # hier statt als Build-Arg. Wert landet im SSR-Init-Snapshot + # und in client-fetches. + PUBLIC_CARDS_API_URL: https://cardecky-api.mana.how + PUBLIC_MANA_AUTH_URL: https://auth.mana.how CARDS_API_URL: https://cardecky-api.mana.how NODE_ENV: production ports: