Skip to content

fix(core): load head styles/scripts from non-template sub-compositions#219

Merged
miguel-heygen merged 2 commits intomainfrom
fix/subcomp-head-styles
Apr 7, 2026
Merged

fix(core): load head styles/scripts from non-template sub-compositions#219
miguel-heygen merged 2 commits intomainfrom
fix/subcomp-head-styles

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen commented Apr 7, 2026

Summary

Fixes a bug where non-template sub-compositions (full HTML documents loaded via data-composition-src) lost all <head> styles and scripts. This affected three code paths:

  1. Runtime (compositionLoader.ts) — browser preview via iframe fetch
  2. Bundler (htmlBundler.ts) — studio preview HTML bundling (this was causing the black preview)
  3. Producer fix is in PR fix(producer): extract head assets from non-template sub-comps + fix postcss ESM #220

What it fixes

Eval prompt #25 (iris-wipe) renders entirely black in both the studio preview and rendered video because scene backgrounds (#EF4444 red, #3B82F6 blue), positioning, and the GSAP CDN script were all in <head> and silently dropped.

Verified

Rebuilt core, started studio preview, fetched the bundled HTML from /api/projects/iris-wipe/preview — confirmed #scene1 { background: #EF4444 } and .scene { position: absolute } are now present in the output.

Root cause

All three code paths did the same thing:

const contentHtml = template ? template.innerHTML : bodyEl.innerHTML;
// ^ <head> content is already lost here

Test plan

  • All 429 core tests pass
  • Studio preview endpoint returns correct bundled HTML with head styles included
  • pnpm --filter @hyperframes/core build succeeds

🤖 Generated with Claude Code

@miguel-heygen miguel-heygen changed the title fix(core): load head styles and scripts from non-template sub-compositions fix(core): load head styles/scripts from non-template sub-compositions Apr 7, 2026
@miguel-heygen miguel-heygen marked this pull request as ready for review April 7, 2026 00:46
@miguel-heygen miguel-heygen force-pushed the fix/lint-infinite-repeat branch from f295a17 to af367d8 Compare April 7, 2026 01:04
@miguel-heygen miguel-heygen force-pushed the fix/subcomp-head-styles branch from 4a47377 to 77fcb40 Compare April 7, 2026 01:04
@miguel-heygen miguel-heygen force-pushed the fix/subcomp-head-styles branch from 2a3a719 to 5e8a67f Compare April 7, 2026 01:25
@miguel-heygen miguel-heygen force-pushed the fix/lint-infinite-repeat branch from dfc54d9 to 12c5b65 Compare April 7, 2026 01:39
@miguel-heygen miguel-heygen force-pushed the fix/lint-infinite-repeat branch from 12c5b65 to 17791d1 Compare April 7, 2026 01:39
@miguel-heygen miguel-heygen force-pushed the fix/subcomp-head-styles branch from 5e8a67f to 2285ae9 Compare April 7, 2026 01:39
Copy link
Copy Markdown
Collaborator Author

miguel-heygen commented Apr 7, 2026

Merge activity

  • Apr 7, 2:53 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 7, 2:55 PM UTC: Graphite rebased this pull request as part of a merge.
  • Apr 7, 3:17 PM UTC: @miguel-heygen merged this pull request with Graphite.

@miguel-heygen miguel-heygen changed the base branch from fix/lint-infinite-repeat to graphite-base/219 April 7, 2026 14:53
@miguel-heygen miguel-heygen changed the base branch from graphite-base/219 to main April 7, 2026 14:53
miguel-heygen and others added 2 commits April 7, 2026 14:54
…tions

When a sub-composition is a full HTML document (not wrapped in
<template>), the composition loader only extracted <style> and
<script> elements from within the [data-composition-id] root
element. Any CSS in <head> (backgrounds, positioning, fonts) or
scripts in <head> (GSAP CDN) were silently dropped.

This caused the iris-wipe eval (prompt 25, scored 1.0/5) to
render entirely black — the scene background colors and absolute
positioning were defined in <head><style> and never loaded.

Now extracts <head> styles and scripts from non-template sub-comp
documents and injects them before the content-level assets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…b-comps

Same bug as the runtime and producer fixes, but in the bundler
used by the studio preview. The bundler's sub-composition
inlining parsed only body.innerHTML for non-template
sub-compositions, dropping all <head> styles and scripts.

This is why the iris-wipe showed black in the studio preview —
the scene backgrounds and GSAP CDN script were in <head>.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@miguel-heygen miguel-heygen force-pushed the fix/subcomp-head-styles branch from 2285ae9 to f8efac2 Compare April 7, 2026 14:54
@miguel-heygen miguel-heygen merged commit f56b4c8 into main Apr 7, 2026
21 checks passed
miguel-heygen added a commit that referenced this pull request Apr 7, 2026
…postcss ESM (#220)

## Summary

Two fixes in the producer:

1. **Head styles/scripts extraction**: mirrors the runtime fix from PR #219. The producer's `inlineSubCompositions()` parsed only `bodyEl.innerHTML` from non-template sub-compositions, discarding all `<head>` content.
2. **Externalize postcss**: postcss is a CJS module with `require("path")` — bundling it into ESM output caused "Dynamic require of path is not supported" at runtime, breaking `npx tsx cli render` and `npx tsx cli preview` from the local dev build.

## Verified

Re-rendered the iris-wipe composition (eval prompt #25, previously scored 1.0/5 — entirely black):

| Frame | Before fix | After fix |
| --- | --- | --- |
| 0\.5s | Black | Red background + "HELLO" text |
| File size | 16\.9 KB (all black) | 64\.8 KB (actual content) |

Scene 1 now renders correctly. Scene 2's clip-path animation has a separate GSAP issue (the lint already warns about it via `scene_layer_missing_visibility_kill`).

## Test plan

- [x] `pnpm --filter @hyperframes/producer build` succeeds
- [x] `node --input-type=module -e "import './dist/index.js'"` loads without error
- [x] Re-render iris-wipe produces visible content (64.8 KB vs 16.9 KB)
- [x] Frame extraction confirms red "HELLO" scene renders correctly
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.

2 participants