Cameron the Dev

How to add a dark mode toggle to your Gatsby site

September 20, 2020

When I created this gatsby blog one of the first things I wanted to add was a dark mode toggle, similar to the one that can be found on Overreacted. After implementing this I have detailed the process below.

To get started you will need to install gatsby-plugin-dark-mode and react-dark-mode-toggle. You can do this by running the following in your terminal if you are using npm:

npm i gatsby-plugin-dark-mode react-dark-mode-toggle

and if you are using yarn you can run:

yarn add gatsby-plugin-dark-mode react-dark-mode-toggle

We then need to add the gatsby-plugin-dark-mode plugin to the plugin section of your gatsby-config.js file. This will look something like this:

plugins: [
    ' gatsby-plugin-dark-mode'

// ... Other plugins would go here
]

We have now told Gatsby we want to use the plugin. So next we are going to create a new react component that will integrate the two modules we have installed.

import React from 'react'
import { ThemeToggler } from 'gatsby-plugin-dark-mode'
import DarkModeToggle from 'react-dark-mode-toggle'

class MyComponent extends React.Component {
  render() {
    return (
      <ThemeToggler>
        {({ theme, toggleTheme }) => (
            <DarkModeToggle
            onChange={e => toggleTheme(e ? 'dark' : 'light')}
            checked={theme === 'dark'}
            size={80}
            speed={2}
          />
        )}
      </ThemeToggler>
    )
  }
}

export default MyComponent

Once you have done the above, you will need to include the component into your layout file. Import it like so:

import MyComponent from './darkModeToggle'

And then add the react component wherever you want inside your layout template by adding: <MyComponent />. Don’t forget to change the naming of the file/component to match what you called your component.

Now if you go to your local site you will see the toggle. If you click the toggle, you will see that it looks like nothing is happening at the moment. However, if you inspect the body element using the web dev tools and then click the toggle you will see a dark class being added and removed.

We can use this class combined with CSS variables to change the colours used in our stylesheet which will enable us to create our dark mode theme. Add the styles below to your CSS file (don’t forget to replace the colours below with your own!). If you don’t have a CSS file already then you will need to create one and include it in your layout.js file.

body {
  --bg: white;
  --textNormal: #222;
  --textTitle: #222;
  --textLink: #ec823a;
  --hr: #ec823a;

  color: var(--textNormal);
  background-color: var(--bg);
}

body.dark {
  -webkit-font-smoothing: antialiased;

  --bg: #222831;
  --textNormal: rgba(255, 255, 255, 0.88);
  --textTitle: white;
  --textLink: #f2a365;
  --hr: #f2a365;
} 

You will then need to go through your current CSS rules and switch out the colour variables for the ones you define above, using the syntax var(--textTitle). You might need to add or remove CSS variables depending on your current styles. If you need help choosing the colours for your dark mode you can check out a site like (colorhunt)[https://colorhunt.co/palettes/dark] to find some inspiration.

If you are using the gatsby-plugin-typography plugin then you will need to tweak any colours you have set so they use the CSS variable. So for example to have our H1 use the textTitle colour we would have:

   h1: {
    color: 'var(--textTitle)'
  },

If everything has been updated correctly you should now be able to go back to your local site, click the toggle and see the site switch between your light and dark theme!