88 lines
2.6 KiB
TypeScript

import { Agentation } from 'agentation'
import { GeistPixelSquare } from 'geist/font/pixel'
import { Barlow } from 'next/font/google'
import localFont from 'next/font/local'
import Script from 'next/script'
import { ClientBootstrap } from './client-bootstrap'
import './globals.css'
const chunkRecoveryScript = `
(() => {
const marker = 'pascal:chunk-recovery-at'
const recoveryParam = '__pascal_reload'
const chunkError = /ChunkLoadError|Failed to load chunk|Loading chunk .* failed|CSS_CHUNK_LOAD_FAILED/i
const recover = (event) => {
const reason = event?.reason
const message = [
event?.message,
reason?.message,
typeof reason === 'string' ? reason : '',
].filter(Boolean).join(' ')
if (!chunkError.test(message)) return
const now = Date.now()
const lastRecovery = Number(sessionStorage.getItem(marker) || 0)
if (now - lastRecovery < 60000) return
sessionStorage.setItem(marker, String(now))
const url = new URL(window.location.href)
url.searchParams.set(recoveryParam, String(now))
window.location.replace(url.toString())
}
window.addEventListener('error', recover, true)
window.addEventListener('unhandledrejection', recover)
window.setTimeout(() => {
sessionStorage.removeItem(marker)
const url = new URL(window.location.href)
if (!url.searchParams.has(recoveryParam)) return
url.searchParams.delete(recoveryParam)
window.history.replaceState(window.history.state, '', url.toString())
}, 10000)
})()
`
const geistSans = localFont({
src: './fonts/GeistVF.woff',
variable: '--font-geist-sans',
})
const geistMono = localFont({
src: './fonts/GeistMonoVF.woff',
variable: '--font-geist-mono',
})
const barlow = Barlow({
subsets: ['latin'],
weight: ['400', '500', '600', '700'],
variable: '--font-barlow',
display: 'swap',
})
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html
className={`${geistSans.variable} ${geistMono.variable} ${GeistPixelSquare.variable} ${barlow.variable}`}
lang="zh-CN"
>
<head>
<Script id="pascal-chunk-recovery" strategy="beforeInteractive">
{chunkRecoveryScript}
</Script>
{process.env.NODE_ENV === 'development' && (
<script async crossOrigin="anonymous" src="//unpkg.com/react-scan/dist/auto.global.js" />
)}
</head>
<body className="font-sans">
<ClientBootstrap>{children}</ClientBootstrap>
{process.env.NODE_ENV === 'development' && <Agentation />}
</body>
</html>
)
}