Originally posted in oh-no.ooo (Fixing Disqus ‘Auto’ theme switching when using Next.js + next-themes), my personal website.
In my last year’s post about the amazing Blaugust event, I’ve been mentioning my issue with setting up my Next.js site combined with next-themes and Disqus commenting platform.
This article is here to make sure I can share my solution, as for as simple it was it might help some people that stumble upon it. Let’s start first with what issue I had, what I’ve done, so that we can walk together through the solution!
What was the issue
After following the Step-By-Step Guide to Adding Dark Mode and Multiple Themes to Your Next.js App written by Luis Cadillo (thank you pal!), I found myself with a neat Dark mode but my Disqus embed (installed through disqus-react npm package) would not update its theme properly, despite its theme settings being on Auto
.
Buggy Disqus theme change at the bottom of my articles
I checked that the settings in <sitename>.disqus.com/admin/settings/general/
were correct, but that didn’t help.
Disqus settings for automatic detection of the color scheme.
The solution
My initial challenge was understanding how Disqus determined which theme to show in the page. Browsing the documentation I stumbled on a piece of useful information:
Light vs. dark color scheme
A light or dark color scheme is automatically selected based on your site’s stylesheets.How is the color scheme determined?
- The light scheme is loaded when the text color Disqus inherits from your site has >= 50% gray contrast: between color: #000000; and color: #787878;
- The dark scheme is loaded in all other instances.
This allowed me to understand how the color scheme in Disqus was determined, but not yet why my changes wouldn’t work. White text on a white background isn’t quite the ‘Auto’ mode I was hoping for!
Searching for some help in StackOverflow, I found my very same problem but no answer to it: Disqus theme not matching background when changing blog theme from dark to light. Despite not finding a solution, I found some comfort in seeing that other peeps had my same problem and that it wasn’t just me being… well… dumb xD
A little bit more digging and googling around brought me to another StackOverflow post, Disqus comments Dark mode renders with white background where Ken Mueller mentions to “Remove the <meta name=”color-scheme” content=”dark” /> from your document.”.
Now, I didn’t have such a thing in my Next.js ecosystem, but I noticed that next-themes applied a style="color-scheme: dark;"
to my main HTML tag.
<html lang="en" class="dark" style="color-scheme: dark;">
My Chrome inspector showing that the HTML tag in my website had this extra style="color-scheme: dark;"
property.
Since messing around with the inspector costs nothing, I’ve simply tried to remove the content of style
and don’t you know… it worked!
Checking next-themes documentation, reading the codebase and bashing my head a little, I seem to understand that this HTML style change comes from the enableColorScheme
setting of next-themes, which by default is set as true
, but for my case would need to be set false
.
const MyApp = ({ Component, pageProps }: AppProps) => { return ( <> <ThemeProvider attribute="class" enableColorScheme={false} > <Provider store={store}> <Component {...pageProps} />
</Provider>
</ThemeProvider>
</>
);
}; export default MyApp;
Wohoo! Works like a charm!
But no, wait!
Now if I am in an article page and I want to switch the theme there, my <DiscussionEmbed>
component from disqus-react won’t update automatically! So what do we do now?
I happen to have this component wrapped in a container for easier setup on my page, and I know that React would re-render a component should its key change… so 1 + 1 I had my 2:
const DisqusComments: FC<DisqusCommentsProps> = ({ url, slug, title }) => { // Import the name of the theme with useTheme() hook // from next-themes const { theme } = useTheme(); const disqusConfig = { url: url, identifier: slug, title: title, }; // Use it as a key={theme} for the DiscussionEmbed component // so that it will re-render should the theme change return ( <div className="my-14"> <DiscussionEmbed key={theme} shortname={"oh-no"} config={disqusConfig} />
</div>
);
}; export default DisqusComments;
Basically, I’ll use the name of the theme to determine whether the Disqus component should re-render, and should someone change the theme in an article page, the Disqus comment section will reload with the correct theme!
At last, all I wanted!
My website Disqus section adapting to both dark and light color schemes. Yay!
Let me know if this helped you somehow, if you had the same issue or if somehow it brought you some help understanding a bit more about the problem for your own specific case!