`document.fonts.ready` resolved before the 4MB Material Symbols woff2 even started loading — it runs in <head>, ahead of any element that would trigger the lazy fetch. The `fonts-loaded` class landed early, so icons rendered blank until a second load served the font from disk cache. Load the face explicitly and swap visibility for opacity, with a 3s fallback so icons never stay hidden if the font fails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
1.7 KiB
JavaScript
52 lines
1.7 KiB
JavaScript
import { Inter } from "next/font/google";
|
|
import { GoogleAnalytics } from "@next/third-parties/google";
|
|
import "material-symbols/outlined.css";
|
|
import "./globals.css";
|
|
import { ThemeProvider } from "@/shared/components/ThemeProvider";
|
|
import "@/lib/network/initOutboundProxy"; // Auto-initialize outbound proxy env
|
|
import "@/shared/services/bootstrap"; // Auto-run initializeApp (watchdog, auto-resume tunnel)
|
|
import { initConsoleLogCapture } from "@/lib/consoleLogBuffer";
|
|
import { RuntimeI18nProvider } from "@/i18n/RuntimeI18nProvider";
|
|
|
|
// Hook console immediately at module load time (server-side only, runs once)
|
|
initConsoleLogCapture();
|
|
|
|
const inter = Inter({
|
|
subsets: ["latin"],
|
|
variable: "--font-inter",
|
|
});
|
|
|
|
export const metadata = {
|
|
title: "9Router - AI Infrastructure Management",
|
|
description: "One endpoint for all your AI providers. Manage keys, monitor usage, and scale effortlessly.",
|
|
icons: {
|
|
icon: "/favicon.svg",
|
|
},
|
|
};
|
|
|
|
export const viewport = {
|
|
themeColor: "#0a0a0a",
|
|
};
|
|
|
|
export default function RootLayout({ children }) {
|
|
return (
|
|
<html lang="en" suppressHydrationWarning>
|
|
<head>
|
|
<script
|
|
dangerouslySetInnerHTML={{
|
|
__html: `var d=document,r=d.documentElement,f=function(){r.classList.add('fonts-loaded')};if(d.fonts&&d.fonts.load){d.fonts.load('24px "Material Symbols Outlined"').then(f).catch(f);setTimeout(f,3000)}else{f()}`,
|
|
}}
|
|
/>
|
|
</head>
|
|
<body className={`${inter.variable} font-sans antialiased`}>
|
|
<ThemeProvider>
|
|
<RuntimeI18nProvider>
|
|
{children}
|
|
</RuntimeI18nProvider>
|
|
</ThemeProvider>
|
|
<GoogleAnalytics gaId={"G-LC959F603F"} />
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|