fix(studio): inject runtime env overrides for pre-built SPA mode

VITE_STUDIO_* env vars set in the user's shell had no effect when
running `hyperframes preview` because the pre-built studio bundle had
them baked at Vite build time.

The embedded Hono server now collects VITE_STUDIO_* vars from
process.env and injects them as a `window.__HF_STUDIO_ENV__` script
tag into index.html. The client merges this runtime object on top of
the baked `import.meta.env`, so flags like
VITE_STUDIO_ENABLE_BLOCKS_PANEL=1 work as expected at runtime.
This commit is contained in:
Miguel Ángel
2026-05-21 18:27:29 -04:00
parent f51d324ff5
commit 289aa03499
2 changed files with 32 additions and 2 deletions
+22 -1
View File
@@ -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");
@@ -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 };