import { QueryClient, QueryClientProvider, hydrate } from '@tanstack/react-query' import { createRoot, hydrateRoot } from 'react-dom/client' import { HelmetProvider } from 'react-helmet-async' import { I18nextProvider } from 'react-i18next' import '@/index.css' import App from '@/App' import { createUII18n } from '@/lib/i18n' import { prepareHelpPage } from '@/lib/help' import { currentViewingLocale } from '@/lib/locales' import { localesKeys } from '@/lib/queryKeys' import { applyClientAnimationMode, getClientAnimationMode } from '@/lib/settings' import type { DehydratedState } from '@tanstack/react-query' const helmetContext = { } const client = new QueryClient ({ defaultOptions: { queries: { staleTime: 5 * 60 * 1000, gcTime: 30 * 60 * 1000, retry: 1 } } }) const mount = (serverRendered: boolean) => { const instance = createUII18n (currentViewingLocale ()) const app = ( ) const root = document.getElementById ('root')! if (serverRendered) hydrateRoot (root, app) else createRoot (root).render (app) } const start = () => { applyClientAnimationMode (getClientAnimationMode ()) const bootstrap = document.getElementById ('ssr-state') if (bootstrap == null) { mount (false) return } const storageKey = 'btrc_hub.ssr-recovery' const identity = `${import.meta.url}:${location.pathname}${location.search}` let pending = false let mounted = false const retry = () => { void attempt () } const attempt = async () => { if (pending || mounted) return pending = true try { const data = JSON.parse (bootstrap.textContent ?? '') as { state: DehydratedState; status: number } if (data?.state == null || !(Array.isArray (data.state.queries))) throw new Error ('Invalid SSR query state') hydrate (client, data.state) if (client.getQueryData (localesKeys.index) == null) throw new Error ('Missing SSR locales') const status = await prepareHelpPage (client, new URL (window.location.href)) if (status !== data.status) throw new Error ('Server and browser Help versions differ') mount (true) mounted = true for (const event of ['online', 'focus', 'pageshow']) window.removeEventListener (event, retry) try { sessionStorage.removeItem (storageKey) } catch { // Storage may be unavailable; successful hydration needs no recovery marker. } } catch (error) { console.error ('[SSR] Preparation failed; keeping server HTML', error) // A new document also clears failed dynamic-import module caches. // Never clear the root or attempt CSR over unmatched server markup. try { if (navigator.onLine && sessionStorage.getItem (storageKey) !== identity) { sessionStorage.setItem (storageKey, identity) window.location.reload () } } catch { // Keep the readable document and retry on online/focus/pageshow instead. } } finally { pending = false } } for (const event of ['online', 'focus', 'pageshow']) window.addEventListener (event, retry) retry () } start ()