mercury-web/src/app/layout.tsx

40 lines
1.8 KiB
TypeScript

import "./globals.css";
export const metadata = { title: "Mercury" };
// Runs before paint (in <head>, ahead of hydration) to set the Seed
// color-mode attribute from the persisted preference, avoiding a
// flash-of-incorrect-theme: the server always renders "system" (no
// localStorage access during SSR), so without this the client would briefly
// paint light/system before this script could run post-hydration.
const THEME_INIT_SCRIPT = `
(function () {
try {
var v = localStorage.getItem("mercury.theme");
var mode = v === "light" ? "light-only" : v === "dark" ? "dark-only" : "system";
var el = document.documentElement;
el.setAttribute("data-seed-color-mode", mode);
// Seed's "system" mode resolves dark ONLY when data-seed-user-color-scheme
// reflects the OS preference — the CSS has no prefers-color-scheme media
// query of its own. Sync it from matchMedia so "system" actually follows
// the OS (light-only/dark-only ignore this attribute).
var dark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
el.setAttribute("data-seed-user-color-scheme", dark ? "dark" : "light");
} catch (e) {}
})();
`;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
// suppressHydrationWarning: the inline script below intentionally
// rewrites data-seed-color-mode before hydration (to the persisted
// preference), so it will legitimately differ from this "system"
// server-rendered value — React should not warn about or "fix" that.
<html lang="mn" data-seed data-seed-color-mode="system" suppressHydrationWarning>
<head>
<script dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }} />
</head>
<body>{children}</body>
</html>
);
}