Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

255
Views
Prevent page flash in Next.js 12 with Tailwind CSS class-based dark mode

How can one prevent the page flash when using class-based dark mode in Tailwind CSS with Next.js v12 without using any 3rd party pkgs like next-themes?

I've looked at:

  • this Q&A How to fix dark mode background color flicker in NextJS? and while it's a valid/working solution in Next.js <v12, in v12 it no longer works and throws warnings in dev which suprisingly turn to a build blocking error in prod env 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
  • This article https://www.vidyasource.com/blog/dark-mode-nextjs-tailwindcss-react-hooks however including the script <Script strategy="beforeInteractive" src="/scripts/darkMode.js"/> still results in a page flash as it adds defer to it in the head
  • This official Tailwind CSS dark mode doc on what's required https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually
// 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')
}

I think they restrict putting things in Head from v12 to prepare for Suspense / Streaming / React v18.

Either way, I'm lost on how to do it without next-themes, does anyone know how can we just inject that bit of script to prevent that page flash?

Hope this question makes sense, if not, please give me a shout.

I like simple and minimalistic things, hence the aim to reduce the dependency on 3rd party pkgs, such a simple thing should be possible without overcomplicated solution IMO.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I had the same problem and solved it like this in Next 12.1.0:

  1. Create theme.js within the public folder (mine has the following content):
;(function initTheme() {
  var theme = localStorage.getItem('theme') || 'light'
  if (theme === 'dark') {
    document.querySelector('html').classList.add('dark')
  }
})()
  1. Add <Script src="/theme.js" strategy="beforeInteractive" /> to _app.tsx or _app.jsx. This is important - I tried putting it inside _document.tsx which didn't work. The final _app.tsx looks like this:
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

Works like a charm for me - no flickering and all Next.js magic. :) Hope this works for you too.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!