Files
scoreodonto.com/frontend/index.html
VPS 4 Builder bbbe3705d8 feat(ux): auto-reload anti-tela-branca pós-deploy (stale chunk/bundle)
- watchdog inline no index.html: erro de asset /assets/ (404 de bundle antiga em
  cache), import dinâmico falho, ou #root vazio após 8s → reload automático
- index.tsx: listener vite:preloadError → reload
- anti-loop por timestamp (só recarrega se última tentativa >30s; re-arma sozinho)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 02:55:03 +02:00

70 lines
2.6 KiB
HTML

<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ScoreOdonto CRM</title>
<script>
(function () {
var path = window.location.pathname;
if (path.indexOf('/odonto') !== -1 && !path.endsWith('/') && path.split('/').pop().indexOf('.') === -1) {
var newUrl = path + '/' + window.location.search + window.location.hash;
window.location.replace(newUrl);
}
})();
</script>
<script>
/* Anti-tela-branca pós-deploy: se um asset (bundle/chunk/css) falhar — ex.: index
antigo em cache apontando p/ bundle removida (404) — ou o app não montar,
recarrega UMA vez para pegar o index/bundle novo. O flag é limpo no app ao
montar com sucesso, rearmando a proteção para o próximo deploy. */
(function () {
function reloadOnce() {
try {
var last = +sessionStorage.getItem('__sd_stale_reload__') || 0;
if (Date.now() - last < 30000) return; /* recarregou há <30s → evita loop */
sessionStorage.setItem('__sd_stale_reload__', String(Date.now()));
} catch (_) {}
location.reload();
}
window.addEventListener('error', function (e) {
var t = e && e.target; if (!t) return;
var url = t.src || t.href || '';
if ((t.tagName === 'SCRIPT' || t.tagName === 'LINK') && /\/assets\/|\/index\.tsx/.test(url)) reloadOnce();
}, true);
window.addEventListener('unhandledrejection', function (e) {
var m = e && e.reason && (e.reason.message || String(e.reason));
if (m && /dynamically imported module|module script failed|Failed to fetch/i.test(m)) reloadOnce();
});
window.addEventListener('load', function () {
setTimeout(function () {
var root = document.getElementById('root');
if (root && root.childElementCount === 0) reloadOnce();
}, 8000);
});
})();
</script>
<base href="/">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div id="root"></div>
<div id="toast-container"></div>
<div id="global-error-display"
style="display: none; position: fixed; top: 10px; left: 10px; right: 10px; background-color: #ef4444; color: white; padding: 16px; border-radius: 8px; z-index: 9999; font-family: monospace; font-size: 14px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
</div>
<script type="module" src="/index.tsx"></script>
</body>
</html>