diff --git a/frontend/editor/.env.saas b/frontend/editor/.env.saas index 2de6a435f..ca6c4b0e1 100644 --- a/frontend/editor/.env.saas +++ b/frontend/editor/.env.saas @@ -8,8 +8,7 @@ # Userback feedback widget — leave blank to disable VITE_USERBACK_TOKEN= -# URL subpath prefix for SaaS deployments (e.g. "app" if serving at /app/) — leave blank for root -VITE_RUN_SUBPATH= - # Development-only auth bypass — allows unauthenticated access on localhost in dev mode +# The URL subpath prefix is read from BASE_PATH at runtime, sourced from the +# top-level RUN_SUBPATH env var which Vite consumes at build time. VITE_DEV_BYPASS_AUTH=false diff --git a/frontend/editor/src/core/workers/pixelCompareWorker.ts b/frontend/editor/src/core/workers/pixelCompareWorker.ts index bb57bb75f..987857821 100644 --- a/frontend/editor/src/core/workers/pixelCompareWorker.ts +++ b/frontend/editor/src/core/workers/pixelCompareWorker.ts @@ -395,7 +395,11 @@ self.addEventListener( // the default DOMFilterFactory crashes in a worker calling document.createElementNS. // Resolve CMap/standard-font URLs against the worker's own origin. Vite copies these // directories from pdfjs-dist at build time via viteStaticCopy (see vite.config.ts). - const assetsBase = new URL("/pdfjs/", self.location.origin).toString(); + // import.meta.env.BASE_URL ends with a slash and includes any subpath prefix. + const assetsBase = new URL( + `${import.meta.env.BASE_URL}pdfjs/`, + self.location.origin, + ).toString(); const loaderOpts = (data: ArrayBuffer) => ({ data, diff --git a/frontend/editor/src/proprietary/components/chat/ChatContext.tsx b/frontend/editor/src/proprietary/components/chat/ChatContext.tsx index 6cd473eda..65c2e9dd3 100644 --- a/frontend/editor/src/proprietary/components/chat/ChatContext.tsx +++ b/frontend/editor/src/proprietary/components/chat/ChatContext.tsx @@ -10,6 +10,7 @@ import { useTranslation } from "react-i18next"; import { generateId } from "@app/utils/generateId"; import { useAllFiles, useFileActions } from "@app/contexts/FileContext"; import apiClient from "@app/services/apiClient"; +import { getApiBaseUrl } from "@app/services/apiClientConfig"; import { getAuthHeaders } from "@app/services/apiClientSetup"; import { createChildStub } from "@app/contexts/file/fileActions"; import { @@ -461,13 +462,16 @@ export function ChatProvider({ children }: { children: ReactNode }) { formData.append(`conversationHistory[${i}].content`, message.content); }); - const response = await fetch("/api/v1/ai/orchestrate/stream", { - method: "POST", - body: formData, - headers: getAuthHeaders(), - credentials: "include", - signal: controller.signal, - }); + const response = await fetch( + `${getApiBaseUrl()}/api/v1/ai/orchestrate/stream`, + { + method: "POST", + body: formData, + headers: getAuthHeaders(), + credentials: "include", + signal: controller.signal, + }, + ); if (!response.ok) { let detail: string | undefined; diff --git a/frontend/editor/src/prototypes/components/chat/ChatContext.tsx b/frontend/editor/src/prototypes/components/chat/ChatContext.tsx index 796422bc6..a6c2123ba 100644 --- a/frontend/editor/src/prototypes/components/chat/ChatContext.tsx +++ b/frontend/editor/src/prototypes/components/chat/ChatContext.tsx @@ -9,6 +9,7 @@ import { import { useAllFiles, useFileActions } from "@app/contexts/FileContext"; import { generateId } from "@app/utils/generateId"; import apiClient from "@app/services/apiClient"; +import { getApiBaseUrl } from "@app/services/apiClientConfig"; import { getAuthHeaders } from "@app/services/apiClientSetup"; import { createChildStub } from "@app/contexts/file/fileActions"; import { @@ -440,13 +441,16 @@ export function ChatProvider({ children }: { children: ReactNode }) { formData.append(`conversationHistory[${i}].content`, message.content); }); - const response = await fetch("/api/v1/ai/orchestrate/stream", { - method: "POST", - body: formData, - headers: getAuthHeaders(), - credentials: "include", - signal: controller.signal, - }); + const response = await fetch( + `${getApiBaseUrl()}/api/v1/ai/orchestrate/stream`, + { + method: "POST", + body: formData, + headers: getAuthHeaders(), + credentials: "include", + signal: controller.signal, + }, + ); if (!response.ok) { throw new Error(`AI engine request failed: ${response.status}`); diff --git a/frontend/editor/src/saas/utils/pathUtils.ts b/frontend/editor/src/saas/utils/pathUtils.ts index d2fa188e2..d746fff5b 100644 --- a/frontend/editor/src/saas/utils/pathUtils.ts +++ b/frontend/editor/src/saas/utils/pathUtils.ts @@ -1,6 +1,9 @@ import { URL_TO_TOOL_MAP } from "@app/utils/urlMapping"; +import { BASE_PATH } from "@app/constants/app"; -const SUBPATH = import.meta.env.VITE_RUN_SUBPATH.replace(/^\/|\/$/g, ""); // "app" or "" +// BASE_PATH is "/bpp" or "" (no trailing slash). Strip the leading slash +// to match the legacy SUBPATH shape used below ("bpp" or ""). +const SUBPATH = BASE_PATH.replace(/^\//, ""); /** * Normalize pathname by stripping subpath prefix and trailing slashes diff --git a/frontend/editor/vite-env.d.ts b/frontend/editor/vite-env.d.ts index 2edad0618..d26c3bceb 100644 --- a/frontend/editor/vite-env.d.ts +++ b/frontend/editor/vite-env.d.ts @@ -14,7 +14,6 @@ interface ImportMetaEnv { // SaaS only (.env.saas) readonly VITE_USERBACK_TOKEN: string; - readonly VITE_RUN_SUBPATH: string; readonly VITE_DEV_BYPASS_AUTH: string; // Desktop only (.env.desktop)