diff --git a/packages/core/src/compiler/htmlBundler.ts b/packages/core/src/compiler/htmlBundler.ts
index c21e1e5a2..3512b4b17 100644
--- a/packages/core/src/compiler/htmlBundler.ts
+++ b/packages/core/src/compiler/htmlBundler.ts
@@ -685,7 +685,7 @@ export async function bundleToSingleHtml(
const compStyleChunks: string[] = [...subCompResult.styles];
const compScriptChunks: string[] = [...subCompResult.scripts];
const compExternalScriptSrcs: string[] = [...subCompResult.externalScriptSrcs];
- const compExternalLinkHrefs: string[] = [...subCompResult.externalLinkHrefs];
+ const compExternalLinks = [...subCompResult.externalLinks];
const compVariablesByComp: Record> = {
...subCompResult.variablesByComp,
};
@@ -812,14 +812,12 @@ export async function bundleToSingleHtml(
}
}
- for (const href of compExternalLinkHrefs) {
- if (!document.querySelector(`link[href="${href}"]`)) {
+ for (const link of compExternalLinks) {
+ if (!document.querySelector(`link[href="${link.href}"]`)) {
const linkEl = document.createElement("link");
- linkEl.setAttribute(
- "rel",
- href.includes(".css") || href.includes("css2?") ? "stylesheet" : "preconnect",
- );
- linkEl.setAttribute("href", href);
+ linkEl.setAttribute("rel", link.rel);
+ linkEl.setAttribute("href", link.href);
+ if (link.crossorigin != null) linkEl.setAttribute("crossorigin", link.crossorigin);
document.head.appendChild(linkEl);
}
}
diff --git a/packages/core/src/compiler/inlineSubCompositions.ts b/packages/core/src/compiler/inlineSubCompositions.ts
index 2740f0f41..52c278c70 100644
--- a/packages/core/src/compiler/inlineSubCompositions.ts
+++ b/packages/core/src/compiler/inlineSubCompositions.ts
@@ -97,7 +97,7 @@ export interface InlineSubCompositionsResult {
styles: string[];
scripts: string[];
externalScriptSrcs: string[];
- externalLinkHrefs: string[];
+ externalLinks: { href: string; rel: string; crossorigin?: string }[];
variablesByComp: Record>;
}
@@ -150,7 +150,8 @@ export function inlineSubCompositions(
const styles: string[] = [];
const scripts: string[] = [];
const externalScriptSrcs: string[] = [];
- const externalLinkHrefs: string[] = [];
+ const externalLinks: { href: string; rel: string; crossorigin?: string }[] = [];
+ const seenLinkHrefs = new Set();
const variablesByComp: Record> = {};
for (const hostEl of hosts) {
@@ -227,8 +228,13 @@ export function inlineSubCompositions(
...compDoc.head.querySelectorAll('link[rel="stylesheet"], link[rel="preconnect"]'),
]) {
const href = (link.getAttribute("href") || "").trim();
- if (href && !externalLinkHrefs.includes(href)) {
- externalLinkHrefs.push(href);
+ if (href && !seenLinkHrefs.has(href)) {
+ seenLinkHrefs.add(href);
+ const rel = (link.getAttribute("rel") || "").trim();
+ const crossorigin = link.hasAttribute("crossorigin")
+ ? link.getAttribute("crossorigin") || ""
+ : undefined;
+ externalLinks.push({ href, rel, crossorigin });
}
}
}
@@ -335,5 +341,5 @@ export function inlineSubCompositions(
hostEl.removeAttribute("data-composition-src");
}
- return { styles, scripts, externalScriptSrcs, externalLinkHrefs, variablesByComp };
+ return { styles, scripts, externalScriptSrcs, externalLinks, variablesByComp };
}
diff --git a/packages/producer/src/services/htmlCompiler.ts b/packages/producer/src/services/htmlCompiler.ts
index b68ecd68d..06dab2ebc 100644
--- a/packages/producer/src/services/htmlCompiler.ts
+++ b/packages/producer/src/services/htmlCompiler.ts
@@ -612,15 +612,13 @@ function inlineSubCompositions(
}
}
- if (result.externalLinkHrefs.length && head) {
- for (const href of result.externalLinkHrefs) {
- if (document.querySelector(`link[href="${href}"]`)) continue;
+ if (result.externalLinks.length && head) {
+ for (const link of result.externalLinks) {
+ if (document.querySelector(`link[href="${link.href}"]`)) continue;
const el = document.createElement("link");
- el.setAttribute(
- "rel",
- href.includes(".css") || href.includes("css2?") ? "stylesheet" : "preconnect",
- );
- el.setAttribute("href", href);
+ el.setAttribute("rel", link.rel);
+ el.setAttribute("href", link.href);
+ if (link.crossorigin != null) el.setAttribute("crossorigin", link.crossorigin);
head.appendChild(el);
}
}
diff --git a/skills/hyperframes/references/captions.md b/skills/hyperframes/references/captions.md
index ee1b4953d..f06bcd681 100644
--- a/skills/hyperframes/references/captions.md
+++ b/skills/hyperframes/references/captions.md
@@ -146,6 +146,8 @@ npx hyperframes add caption-highlight # install a specific one
Browse all with previews: [hyperframes.heygen.com/catalog](https://hyperframes.heygen.com/catalog)
+Caption components ship with transparent backgrounds — they're pure overlays. If the underlying video is bright or busy, add a contrast layer (e.g. a semi-transparent dark div) in the host composition beneath the caption sub-composition, not inside the component itself.
+
## Further References
- [dynamic-techniques.md](dynamic-techniques.md) — karaoke, clip-path reveals, slam words, scatter exits, elastic, 3D rotation