Skip to content

ref(debug): Render the email preview in a sandboxed iframe - #122356

Open
oioki wants to merge 3 commits into
masterfrom
oioki/ref/email-preview-iframe
Open

ref(debug): Render the email preview in a sandboxed iframe#122356
oioki wants to merge 3 commits into
masterfrom
oioki/ref/email-preview-iframe

Conversation

@oioki

@oioki oioki commented Aug 20, 2026

Copy link
Copy Markdown
Member

The email preview rendered a whole HTML document inline via dangerouslySetInnerHTML, so the app's CSS and the email's leaked into each other — the app's fonts bled into the email, and the email's styles bled onto the debug page. The result didn't match what any mail client would show.

Render it in a sandboxed iframe instead, so the email is isolated as its own document. Sanitized with DOMPurify (WHOLE_DOCUMENT: true); sandbox without allow-scripts keeps it inert.

Also removes the dangerouslySetInnerHTML sink and corrects html_content's type (it's a plain string, not TrustedHTML).

The old inline render let the app's CSS leak into the email (hence the Rubik heading); the iframe isolates it, so it now renders in the email's own fonts — much closer to how it'd actually look in an inbox, see:

Before (Rubik)

https://sentry.sentry.io/debug/notifications/activity-set-regression/

image

After

image

How it actually looks in the email client (similar font to After)

image

@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Aug 20, 2026
@oioki
oioki force-pushed the oioki/ref/email-preview-iframe branch from fe1b66a to e5d5461 Compare August 25, 2026 16:04
@oioki
oioki marked this pull request as ready for review August 25, 2026 16:13

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e5d5461. Configure here.

Comment thread static/app/debug/notifications/previews/emailPreview.tsx
html_content is a whole HTML document. Splicing it into a div discarded
everything outside <body>, including the viewport meta the email's own
media query depends on, while the one <style> the inliner leaves behind
applied to the debug page itself and pulled in a webfont.

The reverse leaked too: the email uses generic class names like .btn and
.container, which Sentry's own stylesheets also define, so app CSS filled
in wherever the email had not set an inline style. The preview was showing
something no mail client would render.

Render it in an iframe instead, sanitized with WHOLE_DOCUMENT so the shell
survives. The frame is sandboxed without allow-scripts, so the document is
inert; allow-same-origin is only there to read scrollHeight for sizing.

Also corrects html_content's type. It was declared TrustedHTML, but the
endpoint serializes a plain string.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread static/app/debug/notifications/previews/emailPreview.tsx
Address review feedback: attach the iframe load handler with addEventListener and remove it on cleanup, and guard against the load event firing after unmount so a late ResizeObserver isn't created on a detached node.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants