Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions docs/app/components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import { FiSun, FiMonitor, FiMoon } from 'react-icons/fi'

type Mode = 'light' | 'dark' | 'system'

function getStoredMode(): Mode {
if (typeof window === 'undefined') return 'system'
const stored = localStorage.getItem('theme')
if (stored === 'light' || stored === 'dark' || stored === 'system') {
return stored
}
return 'system'
}

function applyTheme(mode: Mode) {
const root = document.documentElement
if (mode === 'system') {
Expand All @@ -16,17 +25,15 @@ function applyTheme(mode: Mode) {
}

export default function ThemeToggle() {
const [mode, setMode] = useState<Mode>('system')
const [mode, setMode] = useState<Mode>(getStoredMode)

useEffect(() => {
const saved = (localStorage.getItem('theme') as Mode) || 'system'
setMode(saved)
applyTheme(saved)
const current = getStoredMode()
applyTheme(current)

const mq = window.matchMedia('(prefers-color-scheme: dark)')
const onChange = () => {
const current = (localStorage.getItem('theme') as Mode) || 'system'
if (current === 'system') applyTheme('system')
if (getStoredMode() === 'system') applyTheme('system')
}
Comment on lines +28 to 37

Copilot AI Apr 15, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useState(getStoredMode) initializes mode during SSR as 'system', and the useEffect now applies the stored theme but never calls setMode(current). This can leave the toggle UI showing the wrong active button until the user clicks (theme applied != state). Update the effect to also sync state (and consider updating state on matchMedia change when mode is system).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback @copilot

mq.addEventListener?.('change', onChange)
return () => mq.removeEventListener?.('change', onChange)
Expand Down
12 changes: 8 additions & 4 deletions docs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type { Metadata } from 'next'
import { Roboto } from 'next/font/google'
import './globals.css'
import ThemeToggle from './components/ThemeToggle'

const roboto = Roboto({
subsets: ['latin'],
weight: ['400', '700'],
display: 'swap',
})

export const metadata: Metadata = {
title: 'Metbit Docs',
description: 'Documentation for Metbit built with Next.js',
Expand All @@ -11,16 +18,13 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet" />
<script
dangerouslySetInnerHTML={{
__html: `(()=>{try{const m=(localStorage.getItem('theme')||'system');const d=window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.setAttribute('data-theme', m==='dark'?'dark':m==='light'?'light':(d?'dark':'light'));}catch(e){}})();`,
}}
/>
</head>
<body>
<body className={roboto.className}>
{children}
<ThemeToggle />
</body>
Expand Down
9 changes: 9 additions & 0 deletions docs/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTypescript from "eslint-config-next/typescript";

export default defineConfig([
...nextVitals,
...nextTypescript,
globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
]);
3 changes: 2 additions & 1 deletion docs/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
Loading
Loading