In november of 2021, a new design was implemented in the blog and it allows users to quickly switch between the light and dark scheme. Everything works as expected, except for one little detail in the blog, the comments section hosted on Disqus. The Disqus component allows users to easily post a comment on the blog and other platforms that use the same service, it works really great and it's been implemented in the blog from the beginning. Only until today I found a problem when switching the Light and Dark scheme from my blog. If the website is loaded with the black scheme and i toggle the light one, Disqus doesn't update the user interface and it remains with the old scheme, even though you define it to set automatically according to the website's color scheme in the control panel of Disqus:
Till the date, it remains as a bug that is quite problematic for some people, but, let's be honest, it's better that way, otherwise imagine some script running in the background checking the color scheme every x seconds to see if the old theme has changed or not. It's worth to mention that this happens only when the implementation of the light and dark scheme is done locally instead of reloading the whole page, as the Disqus components identifies the correct schema everytime it loads from scratch.
In this article, I will show you how to easily solve this problem with a few lines of JavaScript.
1. Identify the logic that switches the theme in your project
The first thing you need to do, is to identify the JavaScript logic that allows the user to switch between a color scheme. For example, imagine that you have a Checkbox, when it's checked, then the dark scheme is used, otherwise not. The example is kinda silly but, you know, easy to understand:
// Custom logic that switches the theme when clicking the button switch scheme
function YourFunctionThatSwitchesTheColorScheme(){
let checkbox = document.getElementById("dark_theme");
if (checkbox.checked) {
// Your Custom code to set dark theme
} else {
// Your Custom code to set light theme
}
}
Once you identify this, you need to dispatch a new event at the end of this method in the document. The name of the event can be whatever you want, the idea is that you will react to this event later in the view where Disqus is loaded. Your method will now look something like this dispatching the method at the end:
// Custom logic that switches the theme when clicking the button switch scheme
function YourFunctionThatSwitchesTheColorScheme(){
let checkbox = document.getElementById("dark_theme");
if (checkbox.checked) {
// Your Custom code to set dark theme
} else {
// Your Custom code to set light theme
}
// Important: create a new event and dispatch
let event = new Event('colorSchemeChanged');
document.dispatchEvent(event);
}
2. Identify where Disqus is initialized
Now theoretically, when the user clicks on the checkbox to switch the website's color scheme, the event will be dispatched in the document and you will be able to react when it's triggered in the view where you load Disqus as usual. You need to find where Disqus is initialized in your project, for example the code that initialized Disqus looks like this:
<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
(function() {
var d = document, s = d.createElement('script');
s.src = 'https://SITE_URL.disqus.com/embed.js'; // Replace SITE_URL with your site's URL
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
Once you know this, proceed with the last step.
3. React to the colorSchemeChanged event
Finally, add the following event listener that will react to the event that we created in the first step when it's dispatched. Once the event is triggered, you can call the reset method from the global DISQUS variable in the window, forcing to re-render the disqus component and therefore fix the color scheme:
// Disqus theme switching
document.addEventListener('colorSchemeChanged', function (e) {
if (document.readyState == 'complete') {
DISQUS.reset({ reload: true, config: disqus_config });
}
});
Happy coding ❤️!