gatsby-plugin-theme-switcher

Because Dark Mode is not enough!

A Gatsby plugin to switch between multiple themes, including dark mode and more! And the best part? No “white flash of death”!

theme-switcher-demo

Install

yarn add gatsby-plugin-theme-switcher

Usage

Add the plugin to your gatsby-config.js.

module.exports = {
  plugins: [
    'gatsby-plugin-theme-switcher',
    ''
  ],
};

Add your themes

This plugin adds a custom class name to the body element of your site and uses CSS variables to customise your color scheme. Add your themes with the .theme-* format:

.theme-twitter {
  --color-bg-primary: #15202B;
  --color-bg-primary-light: #172D3F;
  --color-bg-accent: #1B91DA; 
  --color-bg-accent-light: #1B91DA; 
  --color-bg-secondary: #657786;
  --color-text-link: #1B91DA;    
  --color-bg-compliment: #112b48;
  --color-bg-default: #192734;
  --color-bg-inverse: #1B91DA;
  --color-text-primary: #fff;
  --color-text-secondary: #f2f2f2;
  --color-text-default: #e9e9e9;
  --color-text-default-soft: #6a6a6a;
  --color-text-inverse: #1B91DA;
  --color-text-inverse-soft: #1B91DA;
}

Switching Themes

To switch themes, use the ThemeSwitcher Context

import React, { useContext } from "react"
import { ThemeContext } from 'gatsby-plugin-theme-switcher';

const { theme, switchTheme } = useContext(ThemeContext);

Add A Theme Switcher Component

You can implement your own theme switcher component but here is a basic example:

import React from "react";

const myThemes = [
    {
        id: "theme-midnightgreen",
        name: "Midnight Green",
    },
    {
        id: "theme-spacegray",
        name: "Space Gray",
    },
    {
        id: "theme-twitter",
        name: "Twitter Dark",
    }
]

const ThemePicker = ({ theme, setTheme }) => {
  return (
    <div>
      {myThemes.map((item, index) => {
          const nextTheme = myThemes.length -1 === index ? myThemes[0].id : myThemes[index+1].id;
        
           return item.id === theme ? (
            <div key={item.id} className={item.id}>
              <button
                aria-label={`Theme ${item.name}`}
                onClick={() => setTheme(nextTheme)}
              >
                {item.name}
              </button>
            </div>
          ) : null;
            }
        )}
    </div>
  );
};

export default ThemePicker;

Advanced Usage

 Add your default theme options in gatsby-config.js.

module.exports = {
  plugins: [
   {
      resolve: 'gatsby-plugin-theme-switcher',
      options: {
        defaultDarkTheme: 'theme-dark',
        defaultLightTheme: 'theme-light',
        themeStorageKey: 'my-key',
        minify: true,
      }
    }
  ],
};

Parameters

Option Description
defaultDarkTheme Initial theme name when prefers-color-scheme: dark
defaultLightTheme Initial theme name when preference cannot be determined
themeStorageKey Key to persist the theme name in localStorage. Default = "theme".
minify Minify the injected script using Terser. Default = true.

Credit

This plugin is based on the work and inspired by Sam Larsen-Disney and Josh Comeau

LICENSE

MIT LICENSE