function normalizeBaseUrl(raw: string): string { const trimmed = raw.trim(); return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed; } export function getWebsiteApiBaseUrl(): string { const isBrowser = typeof window !== 'undefined'; const configured = isBrowser ? process.env.NEXT_PUBLIC_API_BASE_URL : process.env.API_BASE_URL ?? process.env.NEXT_PUBLIC_API_BASE_URL; if (configured && configured.trim()) { return normalizeBaseUrl(configured); } // In test-like environments, check if we have any configuration at all const isTestLike = process.env.NODE_ENV === 'test' || process.env.CI === 'true' || process.env.DOCKER === 'true'; // If we're in a test-like environment and have NO configuration, that's an error // But if we have some configuration (even if empty), we should use the fallback if (isTestLike && !process.env.API_BASE_URL && !process.env.NEXT_PUBLIC_API_BASE_URL) { throw new Error( isBrowser ? 'Missing NEXT_PUBLIC_API_BASE_URL. In Docker/CI/test we do not allow falling back to localhost.' : 'Missing API_BASE_URL. In Docker/CI/test we do not allow falling back to localhost.', ); } const fallback = process.env.NODE_ENV === 'development' ? 'http://localhost:3001' : 'http://api:3000'; return normalizeBaseUrl(fallback); }