A Gatsby plugin to switch between multiple themes, including dark mode and more! And the best part? No "white flash of death"!
yarn add gatsby-plugin-theme-switcher
module.exports = {
plugins: [
'gatsby-plugin-theme-switcher',
],
};
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;
}
To switch themes, use the ThemeSwitcher
Context
import React, { useContext } from "react"
import { ThemeContext } from 'gatsby-plugin-theme-switcher';
const { theme, switchTheme } = useContext(ThemeContext);
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 }) => {
if (theme) {
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>
);
}
return null;
};
export default ThemePicker;
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-theme-switcher',
options: {
defaultDarkTheme: 'theme-dark',
defaultLightTheme: 'theme-light',
themeStorageKey: 'my-key',
minify: true,
}
}
],
};
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 . |
This plugin is based on the work and inspired by Sam Larsen-Disney and Josh Comeau
MIT LICENSE