Skip to content

Commit 4acdce8

Browse files
committed
feat(docs): hide marketing hero when the demo is embedded in an iframe
When the demo is loaded in an iframe (it is embedded on roxyapi.com/ui) or opened with ?embed, hide the hero so the host page owns that chrome and the embed starts at the theme and Customize controls. Detect via window.self versus window.top in a head script that sets is-iframed on the html element before paint, so the hero never flashes. The toolbar already carries its own top padding, and direct visits stay unchanged.
1 parent 7163f23 commit 4acdce8

1 file changed

Lines changed: 31 additions & 4 deletions

File tree

apps/docs/index.html

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,20 @@
3333
padding-inline: clamp(1rem, 4vw, 2rem);
3434
}
3535

36-
/* When this page is iframed (e.g. embedded in roxyapi.com/ui), drop the
37-
* outer max-width so the host page's chrome owns the layout. Keep a
38-
* comfortable horizontal pad so charts do not crash into the iframe edge. */
39-
body.is-iframed .container {
36+
/* When this page is iframed (e.g. embedded in roxyapi.com/ui) or opened
37+
* with ?embed, the host page owns the marketing chrome: hide the hero so the
38+
* embed starts at the theme + Customize controls, and drop the outer
39+
* max-width so the host layout owns the width. The .is-iframed class is set
40+
* on <html> in the head script below so the hero never paints first. The
41+
* toolbar already carries padding-block: 1rem, so the controls keep their
42+
* top spacing without any extra padding. */
43+
.is-iframed .container {
4044
max-width: none;
4145
padding-inline: clamp(1rem, 2vw, 1.5rem);
4246
}
47+
.is-iframed .hero {
48+
display: none;
49+
}
4350

4451
.stack > * + * { margin-top: var(--gap, 1rem); }
4552

@@ -590,6 +597,26 @@
590597
]
591598
}
592599
</script>
600+
<script>
601+
// Embed mode. When this page is loaded in an iframe (it is embedded in
602+
// roxyapi.com/ui) or opened with ?embed, mark <html> so the CSS above hides
603+
// the marketing hero and the embed starts at the theme + Customize controls.
604+
// Set here in the head, before the body paints, so the hero never flashes.
605+
// Comparing window.self to window.top is safe across origins; it reads no
606+
// cross-origin property. A standalone tab has self === top and keeps the hero.
607+
(function () {
608+
try {
609+
if (
610+
window.self !== window.top ||
611+
/[?&]embed(?:ded)?\b/.test(window.location.search)
612+
) {
613+
document.documentElement.classList.add('is-iframed');
614+
}
615+
} catch (_) {
616+
document.documentElement.classList.add('is-iframed');
617+
}
618+
})();
619+
</script>
593620
</head>
594621
<body>
595622
<main class="container">

0 commit comments

Comments
 (0)