Thought I'd show how to add dark mode support to you Gatsby site in just 2 minutes.

What we first want to determine is if the users system setting is light or dark mode. Then we want to load preferred theme, preferably before the site is loaded so there isn't a FOUC (flash of unstyled content).

Start by adding this neat script to your gatsby-ssr.js file. It's perfect because it does all the things we specified earlier. Do please read more about "dangerouslySetInnerHTML", it's fairly safe but yeah.

exports.onRenderBody = ({ setHeadComponents }) => {
  setHeadComponents([
    <script
      key="darkmode"
      dangerouslySetInnerHTML={{
        __html: `(function() {  
            function setTheme(theme) {
              window.__theme = theme;
              if (theme === 'dark') {
                document.documentElement.className = 'dark';
              } else {
                document.documentElement.className = '';
              }
            };
            let preferredTheme;
            try {
              preferredTheme = localStorage.getItem('color-theme');
            } catch (e) {}
            let darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
            setTheme(preferredTheme || (darkQuery.matches ? 'dark' : 'light'));
          })();`,
      }}
    />,
  ]);
};

Now we just need to add a dark color scheme. It's really simple if you use semantic naming of colors, read how to here.

I created a dark color scheme by adding ":root.dark" to "layout.css" and added properties that I wanted to be reactive to color mode. Rest of the properties doesn't need to be changed.

:root.dark {
  --color-foreground-primary: #FFFFF5;
  --color-foreground-secondary: #1EB972;
  --color-background-primary: #000000;

And voila, now the color scheme of the site adjusts according to the users system preference. It actually took me longer writing this blog post than adding support for dark mode, lols.

Dark mode picture one
Dark mode picture two