I am new to nextjs and I'm trying to avoid the "flickering/flashing" effect when reloading my website when setting the dark theme.
On my react app, I'm used to read the localStorage directly in a tag embedded in the root index.html and setting a dark background. Here is the code:
<body style="height: 100%; margin: 0px; padding: 0px">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>
const theme = localStorage.getItem('theme');
if (localStorage.getItem('theme') === 'dark') {
document.body.style.backgroundColor = '#141517';
document.body.style.color = '#fff';
} else {
document.body.classList.add('default-theme');
}
</script>
</body>
When it comes to nextJs, I've heard about Server Side Rendering (SSR) and I'd like to avoid breaking optimizations.
I get rid of the flash effect by adding a plain <script> inside the in the _app.tsx :
<>
<Head>
<script src="/theme.js" />
</Head>
<GlobalStyle />
<>
<Providers>
<Component {...pageProps} />
</Providers>
</>
</>
But the development server complains:
Do not add <script> tags using next/head (see <script> tag with src="/theme.js"). Use next/script instead. See more info here: https://nextjs.org/docs/messages/no-script-tags-in-head-component
The doc says to use a <Script> component, I've tried this:
<>
<Head>
</Head>
<GlobalStyle />
<Script src="/theme.js" strategy="beforeInteractive" />
<>
<Providers>
<Component {...pageProps} />
</Providers>
</>
</>
But the flash effect comes back.
Here is my theme.js file:
;(function initTheme() {
var theme = localStorage.getItem('nextColorMode') || 'light'
if (theme === 'dark') {
document.querySelector('html').style.background = 'black'
}
})()
Should I continue with the warning given in the first solution ?