Let the server set the theme based on the cookie sent at request time, which should stop flashing
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { Metadata } from "next";
|
||||
import { cookies } from "next/headers";
|
||||
import "@/scss/nbn.scss";
|
||||
import NavbarClient from "@/components/Navbar";
|
||||
|
||||
@@ -9,25 +10,35 @@ export const metadata: Metadata = {
|
||||
formatDetection: { email: false, address: false, telephone: false },
|
||||
};
|
||||
|
||||
const noFlashThemeScript = `
|
||||
(function() {
|
||||
try {
|
||||
var cookieMatch = document.cookie.match(/(?:^|; )theme=([^;]+)/);
|
||||
var stored = cookieMatch ? decodeURIComponent(cookieMatch[1]) : null;
|
||||
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
var effective = (stored === 'light' || stored === 'dark') ? stored : (prefersDark ? 'dark' : 'light');
|
||||
var el = document.documentElement;
|
||||
if (el.getAttribute('data-bs-theme') !== effective) {
|
||||
el.setAttribute('data-bs-theme', effective);
|
||||
}
|
||||
} catch(_) {}
|
||||
})();`;
|
||||
function themeInitScript() {
|
||||
return `(function(){
|
||||
try {
|
||||
var cookie = document.cookie.split('; ').find(function(c){return c.indexOf('NBN-theme=')===0});
|
||||
var value = cookie ? decodeURIComponent(cookie.split('=').slice(1).join('=')) : null;
|
||||
var theme;
|
||||
if (value === 'light' || value === 'dark') {
|
||||
theme = value;
|
||||
} else {
|
||||
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
theme = prefersDark ? 'dark' : 'light';
|
||||
}
|
||||
var html = document.documentElement;
|
||||
if (html.getAttribute('data-bs-theme') !== theme) {
|
||||
html.setAttribute('data-bs-theme', theme);
|
||||
}
|
||||
} catch(_) {}
|
||||
})();`;
|
||||
}
|
||||
|
||||
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
const cookieStore = await cookies();
|
||||
const stored = cookieStore.get("NBN-theme")?.value;
|
||||
const serverTheme = stored === "light" || stored === "dark" ? stored : "light";
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<html lang="en" data-bs-theme={serverTheme}>
|
||||
<head>
|
||||
<script dangerouslySetInnerHTML={{ __html: noFlashThemeScript }} />
|
||||
<script dangerouslySetInnerHTML={{ __html: themeInitScript() }} />
|
||||
</head>
|
||||
<body>
|
||||
<NavbarClient />
|
||||
|
||||
Reference in New Issue
Block a user