kanban-dev-webapp/src/app/layout.tsx
Dave e7110c44ba fix(theme): no <script> in RSC, OS preference via CSS media query
The earlier 'use next/script beforeInteractive' attempt still emitted a
<script> tag inside React's renderer and therefore still tripped React
19's 'Encountered a script tag' warning on every page that used the root
layout, which is one of the documented triggers of the
chunk.reason.enqueueModel flight-client crash in
vercel/next.js#92362.

ThemeScript now returns null. The first paint picks the OS preference via
a @media (prefers-color-scheme: dark) block in globals.css so no flash
occurs for users on the default. An explicit stored choice is applied
synchronously by ThemeSync (a small client component) on mount — a
trade-off the shadcn dark-mode guide accepts too.

Also fixes the .light class selector the new media-query rule introduces.
2026-09-17 12:06:25 +02:00

35 lines
No EOL
901 B
TypeScript

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { ThemeScript } from "@/components/theme/theme-script";
import { ThemeSync } from "@/components/theme/theme-sync";
import "./globals.css";
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
display: "swap",
});
export const metadata: Metadata = {
title: "Client Board",
description: "Project tracking for client work",
};
export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
// suppressHydrationWarning: ThemeSync mutates the class on <html> when
// it mounts, so server and client markup differ here by design.
<html lang="en" className={inter.variable} suppressHydrationWarning>
<head>
<ThemeScript />
</head>
<body>
{children}
<ThemeSync />
</body>
</html>
);
}