Fixing Disqus 'Auto' theme switching when using Next.js + next-themes

Lucia Nazzaro
Lucia Nazzaro
Lead Frontend Developer
Published
0 views

In my last 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.".

Post edit: remember to escape your < and > next time Lucia xD Disqus reads the whole page as a text and interpreted the meta tag in this paragraph as an actual meta tag!

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.

1<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.

1const MyApp = ({ Component, pageProps }: AppProps) => { 2 return ( 3 <> 4 <ThemeProvider attribute="class" enableColorScheme={false}> 5 <Provider store={store}> 6 <Component {...pageProps} /> 7 </Provider> 8 </ThemeProvider> 9 </> 10 ); 11}; 12 13export 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:

1const DisqusComments: FC<DisqusCommentsProps> = ({ url, slug, title }) => { 2 // Import the name of the theme with useTheme() hook 3 // from next-themes 4 const { theme } = useTheme(); 5 6 const disqusConfig = { 7 url: url, 8 identifier: slug, 9 title: title, 10 }; 11 12 // Use it as a key={theme} for the DiscussionEmbed component 13 // so that it will re-render should the theme change 14 return ( 15 <div className="my-14"> 16 <DiscussionEmbed key={theme} shortname={"oh-no"} config={disqusConfig} /> 17 </div> 18 ); 19}; 20 21export 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!




More Articles

A Blasting August with Blaugust

Having a hard time finding will to work on your blogging website? Blaugust might just be that little spice of inspiration you were looking for!

Performance optimization with useMemo

The useMemo hook is both famous and infamus at the same time. Let's figure out together when we should or should not use it :D