From 017891b1c877eb66d87bd3aa2596a8ea1237a9b8 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:34:39 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(calendar-web):=20use=20clien?= =?UTF-8?q?t=20URL=20in=20browser=20for=20API=20calls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The API client was using the SSR backend URL (http://calendar-backend:3016) in the browser, causing mixed content errors. Now uses the injected client URL (https://calendar-api.mana.how) from window.__PUBLIC_BACKEND_URL__. --- apps/calendar/apps/web/src/lib/api/client.ts | 37 ++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/apps/calendar/apps/web/src/lib/api/client.ts b/apps/calendar/apps/web/src/lib/api/client.ts index 5ca7b5a7b..5b12c0f6a 100644 --- a/apps/calendar/apps/web/src/lib/api/client.ts +++ b/apps/calendar/apps/web/src/lib/api/client.ts @@ -6,24 +6,40 @@ * refreshes expired tokens before making requests. */ +import { browser } from '$app/environment'; import { env } from '$env/dynamic/public'; -import { createApiClient, type ApiResult } from '@manacore/shared-api-client'; +import { createApiClient, type ApiResult, type ApiClient } from '@manacore/shared-api-client'; import { authStore } from '$lib/stores/auth.svelte'; -const API_BASE = env.PUBLIC_BACKEND_URL || 'http://localhost:3014'; +// Use client URL in browser (injected by hooks.server.ts), SSR URL on server +function getApiBase(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) + .__PUBLIC_BACKEND_URL__; + if (injectedUrl) return injectedUrl; + } + return env.PUBLIC_BACKEND_URL || 'http://localhost:3014'; +} /** - * Calendar API client instance + * Calendar API client instance (lazy initialized) * - Auto token handling via authStore.getValidToken() * - Consistent ApiResult response format */ -const api = createApiClient({ - baseUrl: API_BASE, - apiPrefix: '/api/v1', - getAuthToken: () => authStore.getValidToken(), - timeout: 30000, - debug: import.meta.env.DEV, -}); +let _api: ApiClient | null = null; + +function getApi(): ApiClient { + if (!_api) { + _api = createApiClient({ + baseUrl: getApiBase(), + apiPrefix: '/api/v1', + getAuthToken: () => authStore.getValidToken(), + timeout: 30000, + debug: import.meta.env.DEV, + }); + } + return _api; +} /** * Legacy fetchApi interface for backwards compatibility @@ -45,6 +61,7 @@ export async function fetchApi( options: FetchOptions = {} ): Promise> { const { method = 'GET', body, isFormData = false } = options; + const api = getApi(); if (isFormData && body instanceof FormData) { return api.upload(endpoint, body);