fix(studio): align preview fonts with render (#799)

## What

Align Studio preview font handling with final render, and harden the transform hook against failures.

## Why

Preview and render use different font handling. This bug changes text width and makes text layout look different between preview and final render.

## How

- Add a `transformPreviewHtml` hook in `StudioApiAdapter` that adapters can implement to post-process preview HTML before Studio augments it
- Use it in both the Vite adapter and the CLI studio server to inject the same deterministic `@font-face` rules that render uses
- Wrap the hook in a try/catch so a failing transform (e.g. network error during Google Fonts fetch) degrades gracefully — the preview still loads with the original HTML

## Edge cases covered

| Path | Covered |
|------|---------|
| Bundled HTML (adapter returns string) | ✓ |
| Bundle returns null → reads index.html from disk | ✓ |
| Bundle throws → catch-block fallback reads index.html | ✓ |
| Sub-composition preview | ✓ |
| Transform hook throws → graceful fallback to original HTML | ✓ |

## Test plan

- [x] Unit tests added for all five paths above
- [x] Manual testing performed

Closes #797
This commit is contained in:
Miguel Ángel
2026-05-13 21:56:44 +02:00
committed by GitHub
parent 21097f47e2
commit 0d7d38849c
5 changed files with 164 additions and 2 deletions
+6
View File
@@ -209,6 +209,12 @@ export function createStudioServer(options: StudioServerOptions): StudioServer {
}
},
async transformPreviewHtml({ html }) {
const { injectDeterministicFontFaces } =
await import("../../../producer/src/services/deterministicFonts.js");
return injectDeterministicFontFaces(html);
},
getProjectSignature(dir: string): string {
if (resolve(dir) !== resolve(projectDir)) return createProjectSignature(dir);
cachedProjectSignature ??= createProjectSignature(projectDir);