Portal: render placeholder instead of recursing when embedded in an iframe

An un-routed app path falls back to serving the portal, which would otherwise
load the whole shell inside itself endlessly. Detect self-embedding and show a
'not available yet' placeholder instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-01 15:05:50 +00:00
parent ff745b3ec7
commit 06182363cf

View file

@ -5,7 +5,32 @@ import { Dashboard } from './pages/Dashboard'
import { AppFrame } from './pages/AppFrame' import { AppFrame } from './pages/AppFrame'
import { AdminUsers } from './pages/AdminUsers' import { AdminUsers } from './pages/AdminUsers'
// The portal is only ever the top-level frame. If it finds itself loaded inside
// an iframe, it means an app's path fell back to the portal (that app isn't
// deployed or routed in NPM yet) — so render a placeholder instead of recursing
// the whole shell endlessly inside itself.
function EmbeddedFallback() {
return (
<div style={{
height: '100dvh', display: 'flex', alignItems: 'center', justifyContent: 'center',
textAlign: 'center', padding: '2rem', background: 'var(--navy-dark)', color: 'var(--text-muted)',
}}>
<div>
<div style={{ fontSize: '2.5rem', marginBottom: '0.75rem' }}>🚧</div>
<p style={{ fontSize: '1rem', color: 'var(--text)', marginBottom: '0.35rem' }}>
This app isnt available yet
</p>
<p style={{ fontSize: '0.85rem' }}>
It hasnt been deployed or routed on this site.
</p>
</div>
</div>
)
}
export default function App() { export default function App() {
if (window.self !== window.top) return <EmbeddedFallback />
return ( return (
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>