1import React from "react";
2import ReactDOM from "react-dom/client";
3import { createHashHistory, createBrowserHistory } from "@tanstack/react-router";
4
5import "./index.css";
6
7import { prepareProviderAuthDelivery } from "./providerAuthDelivery";
8import { isElectron } from "./env";
9import { getRouter } from "./router";
10import {
11 syncDocumentElectronPlatformClasses,
12 syncDocumentWindowControlsOverlayClass,
13} from "./lib/windowControlsOverlay";
14import { AppRoot } from "./AppRoot";
15import { clearChunkReloadGuard, reloadOnceForChunkLoadError } from "./lib/chunkReloadGuard";
16
17prepareProviderAuthDelivery();
18
19// Electron loads the app from a file-backed shell, so hash history avoids path resolution issues.
20const history = isElectron ? createHashHistory() : createBrowserHistory();
21
22const router = getRouter(history);
23
24if (isElectron) {
25 syncDocumentElectronPlatformClasses(navigator.platform);
26 syncDocumentWindowControlsOverlayClass();
27}
28
29// A failed split-chunk fetch usually means the hashed assets went stale under
30// a deploy; one guarded reload picks up the fresh index.html.
31let chunkLoadFailed = false;
32let reloadScheduled = false;
33window.addEventListener("vite:preloadError", (event) => {
34 chunkLoadFailed = true;
35 if (reloadOnceForChunkLoadError()) {
36 reloadScheduled = true;
37 event.preventDefault();
38 }
39});
40
41const app = <AppRoot router={router} />;
42
43export const startup = router
44 .load()
45 .then(() => {
46 if (reloadScheduled) return;
47 if (!chunkLoadFailed) clearChunkReloadGuard();
48 ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
49 <React.StrictMode>{app}</React.StrictMode>,
50 );
51 })
52 .catch((error: unknown) => {
53 // Let the bootstrap entry show the error unless a reload is already scheduled.
54 if (reloadScheduled) return;
55 throw error;
56 });