Next.js 14+Shadcn-ui设置默认暗色主题遇DOMTokenList报错求助
解决Next.js 14 + Shadcn-ui默认暗色主题的InvalidCharacterError问题
错误原因
当设置ThemeProvider的attribute="class"时,next-themes需要在根DOM元素(通常是<html>)上添加主题类,但你的代码中将ThemeProvider放在了<body>内部,导致组件在尝试操作DOM类名时生成了包含空格的无效token($(dark ? "light" : "dark")),触发InvalidCharacterError。
改为attribute="className"后错误消失,但next-themes无法通过React的className属性正确切换主题,因此默认暗色主题不生效。
解决方案
1. 调整ThemeProvider的包裹范围
将ThemeProvider移至包裹整个<html>标签的位置,让next-themes可以直接操作<html>的class属性:
修改后的layout.tsx代码:
import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; import MainNav from "@/components/MainNav"; import { ThemeProvider } from "@/components/theme-provider"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { title: "Ticket Application", description: "Generated by Vlodex", }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange > <html lang="en"> <body className={inter.className}> <nav className="flex flex-col items-center border-b mb-5 px-5 py-3"> <div className="max-w-6xl w-full"> <MainNav /> </div> </nav> <main className="flex flex-col items-center"> <div className="max-w-6xl w-full">{children}</div> </main> </body> </html> </ThemeProvider> ); }
2. 配置Tailwind支持class模式的暗色主题
确保tailwind.config.ts中设置darkMode: "class",让Tailwind识别.dark类来应用暗色样式:
import type { Config } from "tailwindcss"; const config: Config = { darkMode: "class", content: [ "./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}", ], theme: { extend: {}, }, plugins: [], }; export default config;
3. 确认全局样式配置
检查globals.css是否正确引入Tailwind指令,可按需添加自定义暗色主题样式:
@tailwind base; @tailwind components; @tailwind utilities; /* 可选:自定义暗色主题基础样式 */ .dark { @apply bg-gray-900 text-white; }
原理说明
- 将
ThemeProvider包裹<html>后,next-themes会直接在<html>标签上添加/移除.dark类,避免DOM操作时的无效token问题。 - Tailwind的
darkMode: "class"配置会让框架自动识别.dark类,切换对应主题的样式规则。 defaultTheme="dark"会在页面加载时默认给<html>添加.dark类,实现默认暗色主题生效。
内容的提问来源于stack exchange,提问作者Lucarus An
相关产品推荐
相关产品推荐

