From d4ea026b44c59ac10c6875cea06240861cea4e94 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 16 Apr 2026 18:25:01 -0400 Subject: [PATCH] dynamically select API host for development / production --- frontend/apps/artcraft-website/src/main.tsx | 12 +----------- .../api/src/lib/config/StorytellerApiHostStore.ts | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontend/apps/artcraft-website/src/main.tsx b/frontend/apps/artcraft-website/src/main.tsx index d966684c4b..89674eafb6 100644 --- a/frontend/apps/artcraft-website/src/main.tsx +++ b/frontend/apps/artcraft-website/src/main.tsx @@ -3,7 +3,7 @@ import { BrowserRouter } from "react-router-dom"; import * as ReactDOM from "react-dom/client"; import { GoogleOAuthProvider } from "@react-oauth/google"; import App from "./app/app"; -import { StorytellerApiHostStore, UsersApi } from "@storyteller/api"; +import { UsersApi } from "@storyteller/api"; const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID; @@ -11,16 +11,6 @@ const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement, ); -// In development, route API through the Vite dev server origin to avoid CORS -if (import.meta.env.DEV) { - try { - const origin = window.location.origin; - StorytellerApiHostStore.getInstance().setApiSchemeAndHost(origin); - } catch (e) { - console.warn("Failed to set dev API host override", e); - } -} - // Cache the referrer immediately — it can change or disappear on navigation. // Only set once so subsequent in-site navigations don't overwrite the original. if (!(window as any).cached_referrer) { diff --git a/frontend/libs/api/src/lib/config/StorytellerApiHostStore.ts b/frontend/libs/api/src/lib/config/StorytellerApiHostStore.ts index c90da8cb2f..d39e6318e5 100644 --- a/frontend/libs/api/src/lib/config/StorytellerApiHostStore.ts +++ b/frontend/libs/api/src/lib/config/StorytellerApiHostStore.ts @@ -1,5 +1,6 @@ // Artcraft / Storyteller API backend -const DEFAULT_API_HOST = "https://api.storyteller.ai"; +const DEFAULT_API_HOST_PRODUCTION = "https://api.storyteller.ai"; +const DEFAULT_API_HOST_DEVELOPMENT = "http://localhost:12345"; // NB(bt,2025-09-25): 'nx' is creating multiple copies of the library with name // mangling, so the singleton pattern fails to resolve to a single instance. @@ -32,7 +33,8 @@ export class StorytellerApiHostStore { if ((window as any).STORYTELLER_API_HOST_STORE !== undefined) { return (window as any).STORYTELLER_API_HOST_STORE; } - const instance = new StorytellerApiHostStore(DEFAULT_API_HOST); + const defaultValue = StorytellerApiHostStore.getDefaultApiSchemeAndHost(); + const instance = new StorytellerApiHostStore(defaultValue); (window as any).STORYTELLER_API_HOST_STORE = instance; return instance; } @@ -66,4 +68,12 @@ export class StorytellerApiHostStore { private constructor(apiSchemeAndHost: string) { this.apiSchemeAndHost = apiSchemeAndHost; } + + private static getDefaultApiSchemeAndHost(): string { + // NB: hostname can be empty string + if (window.location.hostname === "localhost") { + return DEFAULT_API_HOST_DEVELOPMENT; + } + return DEFAULT_API_HOST_PRODUCTION; + } }