Skip to content

feat(studio-server): preview variable injection + render variables forwarding#2049

Open
jrusso1020 wants to merge 1 commit into
07-07-feat_sdk_variable_usage_scan_preview-values_adapter_seamfrom
07-07-feat_studio-server_preview_variable_injection_render_variables_forwarding
Open

feat(studio-server): preview variable injection + render variables forwarding#2049
jrusso1020 wants to merge 1 commit into
07-07-feat_sdk_variable_usage_scan_preview-values_adapter_seamfrom
07-07-feat_studio-server_preview_variable_injection_render_variables_forwarding

Conversation

@jrusso1020

@jrusso1020 jrusso1020 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

What

Fourth PR of the template-variables stack: the HTTP plumbing.

  • Preview routes (/preview and /preview/comp/*) accept ?variables=<url-encoded json> and inject window.__hfVariables = {...} before the runtime and any composition script — the exact global the engine sets via evaluateOnNewDocument at render time, so preview-with-values cannot diverge from render output
  • POST /projects/:id/render accepts variables and forwards them through StudioApiAdapter.startRender into the producer's RenderConfig.variables — the same channel hyperframes render --variables uses. Wired in both adapters (CLI embedded server + vite dev adapter)

Why

Render-time injection existed; preview had no equivalent, so "preview with values" was impossible. Mirroring the engine's exact injection mechanism (rather than a bespoke postMessage protocol) is what makes the Studio preview render-truthful.

How

Safety/correctness details worth reviewing:

  • Values are <-escaped against </script> breakout
  • Malformed payloads 400 instead of silently previewing defaults (the param is new, so no existing consumer regresses; empty param still serves normally)
  • The ETag is salted with a hash of the payload so cached previews revalidate when values change (verified: three distinct ETags for none/A/B values)
  • Injection insertion is quirks-mode-safe: <head…><html…> → after doctype → prepend (review fix — the original bare-<head> regex could land the tag before the doctype)
  • Payload validation is one shared helper (helpers/variablesPayload.ts) used by both routes

Test plan

  • Route tests: injection placement + escaping, 400s on invalid/array payloads, ETag variance, sub-composition injection, render forwarding/omission/rejection (56 tests in the two route files)
  • Live HTTP smoke test against a running server: injection present with correct values, 400s, ETag variance (see fix(studio): code-review and live-test fixes for the variables stack #2052)
  • Wire-level check: Studio's Export click POSTs variables to this route

🤖 Generated with Claude Code

…rwarding

Fourth PR of the template-variables Studio stack — the HTTP plumbing.

- preview routes (/preview and /preview/comp/*) accept
  ?variables=<url-encoded json> and inject
  `window.__hfVariables = {...}` into <head>, before the runtime and any
  composition script — the exact global the engine sets via
  evaluateOnNewDocument at render time, so preview-with-values cannot
  diverge from render output. Values are escaped against </script>
  breakout, malformed payloads 400 instead of silently previewing
  defaults, and the ETag is salted with a hash of the payload so cached
  previews revalidate when values change.
- POST /projects/:id/render accepts variables ({variableId: value}) and
  forwards them through StudioApiAdapter.startRender into the producer's
  RenderConfig.variables — the same channel `hyperframes render
  --variables` uses. Wired in both adapters (CLI embedded server + vite
  dev adapter).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jrusso1020 jrusso1020 force-pushed the 07-07-feat_studio-server_preview_variable_injection_render_variables_forwarding branch from c843527 to dc24770 Compare July 8, 2026 08:00
@jrusso1020 jrusso1020 force-pushed the 07-07-feat_sdk_variable_usage_scan_preview-values_adapter_seam branch from a2085a5 to 6acf033 Compare July 8, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant