use*_*025 15 javascript reactjs next.js tailwind-css
在 Tailwind CSS 中使用基于类的深色模式和 Next.js v12 时,如何防止页面闪烁,而不使用任何 3rd 方 pkg(例如 next-themes)?
我看过:
Do not add <script> tags using next/head (see inline <script>). Use next/script instead. See more info here: https://nextjs.org/docs/messages/no-script-tags-in-head-component<Script strategy="beforeInteractive" src="/scripts/darkMode.js"/>仍然会导致页面闪烁,因为它添加defer到了head// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
Run Code Online (Sandbox Code Playgroud)
Head我认为他们限制从 v12开始放入内容来为 Suspense / Streaming / React v18 做准备。
不管怎样,我不知道如何在没有下一个主题的情况下做到这一点,有谁知道我们如何注入那段脚本来防止页面闪烁?
希望这个问题有意义,如果没有,请给我留言。
我喜欢简单和简约的东西,因此目标是减少对第 3 方 pkgs 的依赖,这样一个简单的事情应该是可能的,而不需要过于复杂的解决方案 IMO。
Ron*_*thl 19
我遇到了同样的问题,并在 Next 12.1.0 中这样解决:
theme.js在文件夹内创建public(我的有以下内容):;(function initTheme() {
var theme = localStorage.getItem('theme') || 'light'
if (theme === 'dark') {
document.querySelector('html').classList.add('dark')
}
})()
Run Code Online (Sandbox Code Playgroud)
<Script src="/theme.js" strategy="beforeInteractive" />到_app.tsx或_app.jsx. 这很重要 - 我尝试将其放入其中_document.tsx但不起作用。最终_app.tsx效果如下:import '../styles/globals.css'
import type { AppProps } from 'next/app'
import Head from 'next/head'
import Script from 'next/script'
function App({ Component, pageProps }: AppProps) {
return <>
<Head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<Script src="/theme.js" strategy="beforeInteractive" />
<Component {...pageProps} />
</>
}
export default App
Run Code Online (Sandbox Code Playgroud)
对我来说就像一个魅力 - 没有闪烁和所有 Next.js 的魔力。:) 希望这也适合你。
NextJS 13 与应用程序路由器:
直接查看 Twailwind 网站的页面源代码(通过单击 Chrome MacOS)后,我们可以看到他们正在使用他们在黑暗模式文档command+option+u中描述的确切策略。
然而,将此与NextJs 的内联脚本优化相结合将不起作用,因为它们将内联脚本的内容包装在对 next_js 的调用中,这最终要求页面在设置暗模式之前加载 NextJS(因此是 FOUC)。
为了避免这种情况,我们可以在根布局中使用script不进行优化的普通标签,并使用属性设置其内容,如下所示:dangerouslySetInnerHTML
<html lang="en" suppressHydrationWarning>
<head>
<script dangerouslySetInnerHTML={{
__html: `
try {
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
} catch (_) {}
`
}}/>
{/* Other Meta Tags, Links, Etc... */}
</head>
<body className="text-slate-500 dark:text-slate-400 bg-white dark:bg-slate-900">
{/* Content */}
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这样,我们的脚本将是页面加载时首先执行的脚本之一,从而防止出现无样式内容。
[编辑]:
Prop 'className' did not match当“dark”类存在于客户端 HTML 中但不存在于服务器渲染的 HTML 中时,此方法会导致 NextJS 在开发模式下引发警告。这是可以预料的,因为我们在 NextJS 有机会验证它之前就改变了 HTML 的结构。我们可以通过设置手动抑制警告suppressHydrationWarning我们可以通过在开始的 HTML 标签上
干杯!
| 归档时间: |
|
| 查看次数: |
6248 次 |
| 最近记录: |