stack/apps
devin-ai-integration[bot] 65362f3efb
fix(dashboard): prevent blank email preview when switching themes (#1514)
## Problem

When switching themes in the email drafts/template editor, the preview
occasionally shows the loading spinner and then goes completely blank.

## Cause

`EmailPreview` remounts its preview subtree (and thus the `<iframe>`)
via a `key` on `EmailPreviewErrorBoundary` whenever the inputs that
affect the rendered output change. That key was built from the
template/theme TSX source + edit mode, but **omitted `themeId`**.

Switching only the selected theme changes `themeId` without changing the
source, so the key stayed the same. React then reused the existing
`<iframe>` element and merely mutated its `srcDoc` attribute in place.
Replacing `srcDoc` on a live sandboxed iframe is intermittently not
repainted by the browser, leaving a blank preview after the loading
state.

The old key also concatenated values without a separator, which could
collide.

## Fix

Include `themeId` (and `templateId` / `editableSource`) in the remount
key and build it with a collision-safe serialization. A theme switch now
remounts the preview subtree, so a fresh iframe is mounted and loads its
`srcDoc` reliably instead of mutating it in place. This also resets
stale error-boundary state when moving from a broken theme to a working
one.

Single-line, behavior-preserving change.


Link to Devin session:
https://app.devin.ai/sessions/b269b97b40db4015a8770f77a13c10ea

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes a blank email preview when switching themes in the dashboard
editor by remounting the preview iframe. The preview now reliably
updates on theme changes and resets stale error state.

- **Bug Fixes**
- Updated `EmailPreviewErrorBoundary` key to include `themeId`,
`templateId`, `editableSource`, `editMode`, and debounced theme/template
TSX sources, serialized with JSON and joined with a null delimiter.
- Remounts the iframe on theme switch instead of mutating `srcDoc`,
preventing intermittent blank renders.

<sup>Written for commit 331a0fa071.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1514?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
Co-authored-by: Armaan Jain <84474476+Developing-Gamer@users.noreply.github.com>
2026-06-03 18:31:58 -07:00
..
backend [Fix]: Can now switch subscriptions/ create checkout urls even when stripeAccountId is null with test mode (#1519) 2026-06-03 18:05:12 -07:00
dashboard fix(dashboard): prevent blank email preview when switching themes (#1514) 2026-06-03 18:31:58 -07:00
dev-launchpad chore: update package versions 2026-06-04 00:19:36 +00:00
e2e [Fix]: Can now switch subscriptions/ create checkout urls even when stripeAccountId is null with test mode (#1519) 2026-06-03 18:05:12 -07:00
hosted-components chore: update package versions 2026-06-04 00:19:36 +00:00
internal-tool chore: update package versions 2026-06-04 00:19:36 +00:00
mcp chore: update package versions 2026-06-04 00:19:36 +00:00
mock-oauth-server chore: update package versions 2026-06-04 00:19:36 +00:00
oauth-mock-server In-source unit tests (#429) 2025-02-14 11:47:52 -08:00
skills chore: update package versions 2026-06-04 00:19:36 +00:00