Skip to content

fix(web): drop chrome bar — render HTML like an .html file#21

Merged
alextnetto merged 1 commit into
mainfrom
html-no-chrome
May 16, 2026
Merged

fix(web): drop chrome bar — render HTML like an .html file#21
alextnetto merged 1 commit into
mainfrom
html-no-chrome

Conversation

@alextnetto
Copy link
Copy Markdown
Member

Symptom

HTML pages on Pagent rendered with a 33 px header above the iframe ("✦ AI-generated content" + a Report mailto link). Product call: HTML pages should render identically to opening the .html file directly — no chrome, no overlay.

Fix

  • apps/web/main.ts
    • Remove REPORT_EMAIL const + TODO.
    • Remove the .html-chrome* and .html-stack CSS rules.
    • renderHtml() returns the iframe directly (no flex-column wrapper, no <header>).
  • apps/web/html-renderer.ts
    • Iframe style moves from flex:1 1 auto;…;min-height:0 to width:100%;height:100vh;border:0;display:block. The iframe now pins to the viewport on its own; the flex parent was only needed when the chrome bar was sharing space.

Security note

Three defense layers unchanged:

  1. Server-side DOMPurify sanitization (strips <script>, on-handlers, dangerous URLs).
  2. Strict meta-CSP inside the srcdoc (default-src 'none' + narrow re-enables).
  3. sandbox="" iframe (opaque origin, no JS, no top-nav, no forms, no popups).

CI tripwire still in place: html-renderer.test.ts asserts sandbox stays empty.

The chrome bar was a visual disclosure, not a security boundary.

Diff

apps/web/html-renderer.ts |  6 +++++-
apps/web/main.ts          | 54 ++-------------------------
2 files changed, 10 insertions(+), 50 deletions(-)

Test plan

  • npm run typecheck, npm run lint, npm test (237 pass) — green
  • After deploy: visit https://pagent.link/ — page renders edge-to-edge, no header bar

The shell was rendering a 33 px header above the iframe with
"AI-generated content" + a Report mailto: link. Product call is now
to render HTML pages with no chrome at all, so a Pagent URL feels
identical to opening the .html file directly.

Removes:
- The REPORT_EMAIL constant + accompanying TODO
- .html-chrome / .html-chrome-label / .html-chrome-report / .html-stack CSS
- The <header role="banner"> + Report link from renderHtml()
- The flex-column wrapper (iframe is now the only child)

Iframe styling moves from `flex:1 1 auto;...;min-height:0` (designed
for the flex parent) to `width:100%;height:100vh;border:0;display:block`
so it pins to the viewport directly.

Security boundary is unchanged. The three defense layers — server-side
DOMPurify, meta-CSP in the srcdoc, iframe sandbox="" — all stay. The
chrome bar was a visual disclosure, not a security control.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pagent Ready Ready Preview, Comment May 16, 2026 0:12am

Request Review

@alextnetto alextnetto merged commit d7b6575 into main May 16, 2026
3 checks passed
@alextnetto alextnetto deleted the html-no-chrome branch May 16, 2026 00:13
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.

1 participant