
A mouthful
To put it simple, we're going to cover 3 parts in this guide.
- Dark Mode toggle button
- Auto Mode based on browser preferences
- Save mode as a browser cookie
These 3 parts will be covered in 3 sections of this article.
- Lazy Guide: Inject your code through the Ghost admin panel
- Hard Coded: Add the code to your theme
- Step by step code explanation
Cookies?
Cookies are simple text values saved on the client's computer. The idea is to store information and remember it when you return to the website. Cookies are stored to create a better personal experience.
Without cookies, a website is like a goldfish who loses its memory every time you visit a new page. Once you visit a new page, it doesnβt remember who you are. Learn More
We store our dark mode cookie to remember the dark mode preference of the user. If we don't store a cookie, the mode of preferences will reset on each page load. This means when we try to navigate to a new page, the mode will reset. That's why we store a cookie, to create a better experience for the user.
Lazy Guide
For those of you who don't want to hard code, but rather inject the code through the Ghost admin panel, can follow the "Lazy Guide".
In the Site Header paste the following code.
<style>
.dark-mode-toggle {
margin-right: 5px;
}
</style>
In the Site Footer paste the following code.
<script>
$('div.gh-social').prepend('<a href="#" onclick="themeToggle()" class="dark-mode-toggle">π</a>');
(function() {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && localStorage.getItem('theme') == null) {
document.documentElement.classList.add('dark-mode');
localStorage.setItem("theme", "dark-mode");
}
let cookie = localStorage.getItem("theme") || "";
if(cookie){
document.documentElement.classList.add(cookie);
}
})();
function themeToggle() {
document.documentElement.classList.toggle("dark-mode");
let theme = localStorage.getItem("theme");
if (theme && theme === "dark-mode") {
localStorage.setItem("theme", "");
} else {
localStorage.setItem("theme", "dark-mode");
}
}
</script>
Hit Save and you're done.
Hard Coded
HTML / Handlebars
First we will add our button that we'll configure later as a toggle.
<a href="#" onclick="themeToggle()" class="dark-mode-toggle">π</a>
Find your current theme folder and open the default.hbs file. Go to line 45 and paste the above code right under the gh-social div.
<div class="gh-social">
<a href="#" onclick="themeToggle()" class="dark-mode-toggle">π</a>
{{#if @site.facebook}}
<a class="gh-social-facebook" href="{{facebook_url @site.facebook}}" title="Facebook" target="_blank" rel="noopener">{{> "icons/facebook"}}</a>
{{/if}}
{{#if @site.twitter}}
<a class="gh-social-twitter" href="{{twitter_url @site.twitter}}" title="Twitter" target="_blank" rel="noopener">{{> "icons/twitter"}}</a>
{{/if}}
</div>
Styling
Add the following code to your CSS stylesheet. It's a minor change to align the icon with the already existing social icons.
.dark-mode-toggle {
margin-right: 5px;
}
Javascript
We're going to add 2 functions. The first one will start on page load.
(function() {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && localStorage.getItem('theme') == null) {
document.documentElement.classList.add('dark-mode');
localStorage.setItem("theme", "dark-mode");
}
let cookie = localStorage.getItem("theme") || "";
if(cookie){
document.documentElement.classList.add(cookie);
}
})();
The second function will be triggered by the toggle button we just created.
function themeToggle() {
document.documentElement.classList.toggle("dark-mode");
let theme = localStorage.getItem("theme");
if (theme && theme === "dark-mode") {
localStorage.setItem("theme", "");
} else {
localStorage.setItem("theme", "dark-mode");
}
}
That's it!
If you'd like to have a better understanding of the above code keep reading the step by step code explanation.
Step by step code explanation
Page load function
This if clause checks for the preferred color scheme of the browser's settings. It also checks if the cookie hasn't already been set. We do this because otherwise this would override our toggle button.
Then we add the class dark-mode to the html element.
After that we store a cookie called theme with the value dark-mode.
(function() {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && localStorage.getItem('theme') == null) {
document.documentElement.classList.add('dark-mode');
localStorage.setItem("theme", "dark-mode");
}
let cookie = localStorage.getItem("theme") || "";
if(cookie){
document.documentElement.classList.add(cookie);
}
})()
After the if clause we create a variable called cookie which will get the cookie called theme from the client. We then add the theme variable as a class to the html element. On every page load the html element will be modified with the appropriate theme class.
Trigger function
Our html button has an attribute called onclick which will trigger a Javascript function with that name.
<a href="#" onclick="themeToggle()" class="dark-mode-toggle">π</a>
When triggered we toggle the class dark-mode to the html element.
We then create a variable called theme which will get our cookie called theme.
After that we do a check if the cookie already exists and if it's set to dark-mode.
If it exists, we'll change the cookie and remove the value "dark-mode". This creates an empty cookie called theme. If it's not already set or the theme isn't set to dark-mode, we set the cookie value to dark-mode.
function themeToggle() {
document.documentElement.classList.toggle("dark-mode");
let theme = localStorage.getItem("theme");
if (theme && theme === "dark-mode") {
localStorage.setItem("theme", "");
} else {
localStorage.setItem("theme", "dark-mode");
}
}