Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion packages/cli/src/server/studioServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,22 @@ export function createStudioServer(options: StudioServerOptions): StudioServer {
app.get("/icons/*", serveStudioStaticFile);
app.get("/favicon.svg", serveStudioStaticFile);

// ── Runtime env injection ───────────────────────────────────────────────
// When the studio is served as a pre-built SPA, Vite `VITE_STUDIO_*` env
// vars were baked at build time. Collect any such vars from the current
// process.env and inject them as `window.__HF_STUDIO_ENV__` so the client
// can pick them up at runtime, overriding the baked defaults.
function buildRuntimeEnvScript(): string {
const overrides: Record<string, string> = {};
for (const [key, value] of Object.entries(process.env)) {
if (key.startsWith("VITE_STUDIO_") && value !== undefined) {
overrides[key] = value;
}
}
if (Object.keys(overrides).length === 0) return "";
return `<script>window.__HF_STUDIO_ENV__=${JSON.stringify(overrides)};</script>`;
}

// SPA fallback
app.get("*", (c) => {
const indexPath = resolve(studioDir, "index.html");
Expand Down Expand Up @@ -540,7 +556,12 @@ export function createStudioServer(options: StudioServerOptions): StudioServer {
500,
);
}
return c.html(readFileSync(indexPath, "utf-8"));
let html = readFileSync(indexPath, "utf-8");
const envScript = buildRuntimeEnvScript();
if (envScript) {
html = html.replace("<head>", `<head>${envScript}`);
}
return c.html(html);
});

return { app, watcher };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ export function resolveStudioBooleanEnvFlag(
// and downstream `env[name]` reads would crash. Fall back to `{}` so
// every flag resolves to its declared default outside Vite. Direct
// property access keeps Vite's compile-time transform happy.
const env = (import.meta.env ?? {}) as StudioFeatureFlagEnv;
//
// When the studio is served as a pre-built SPA by the embedded Hono server,
// `import.meta.env` values were baked at build time. The server injects
// `window.__HF_STUDIO_ENV__` with any `VITE_STUDIO_*` env vars from the
// user's shell, so runtime overrides take precedence over baked defaults.
const runtimeEnv =
typeof window !== "undefined"
? ((window as Window & { __HF_STUDIO_ENV__?: StudioFeatureFlagEnv }).__HF_STUDIO_ENV__ ?? {})
: {};
const env = { ...(import.meta.env ?? {}), ...runtimeEnv } as StudioFeatureFlagEnv;

export const STUDIO_PREVIEW_MANUAL_EDITING_ENABLED = resolveStudioBooleanEnvFlag(
env,
Expand Down
Loading