Dynamic Themes with GatsbyJS
I was bored this Saturday and decided to try something. I wasn't exactly sure how possible it would be since GatsbyJS generates static pages. Naively I thought whatever gets thrown into
gatsby-config.js would be static as well... The answer is still technically yes, with Styled Components, color themes are dynamically toggled by
withTheme() using what is statically set. However, it's possible to interupt that process and do something else.
To clarify what I mean about "themes", in this context I do not mean what Gatsby refers to as "Themes". This post strictly shows you how it's possible to change the color theme. However, this has opened the door to some interesting possibilities and I'm certain this is possible with other JS-in-CSS methods. Personally, I'm content with using Styled Components for my personal site so this example is using this particular plugin.
Example Using Styled Components
After following the instructions for using Styled Components in GatsbyJS, I created a new file called
customThemes.js and edited
Before I get ahead of myself, here is how I have personallly written my
darkTheme for this site:
gatsby-config.js file, we import the above themes for
gatsby-styled-components-dark-mode to handle:
Adding Custom Themes
Within the same folder as
themes.js add a new file. Take note that I am also importing the default themes. You'll see that there is a new object called
halloween 🎃 with it's own light and dark themes. Also wrritten in this file are two functions
setTheme will only be exportable and will be used in
Modifying the Global Stylesheet
setTheme() and add that to
Each time the theme is toggled by the
useStyledDarkMode() hook, it actively refreshes the global stylesheet on client-side.
setTheme() interupts the default themes from getting used and checks the month. If it happens to be October, it will instead replace our themes with the custom
halloween themes, returning the required CSS variables that controls all of our components' styles.
As a bonus, it's also possible with replacing fonts. So if I wanted to, I can replace the current font with something "spooky" (which I'm planning to 👻). And since this is essentially Sass, you can throw in custom functions as well. Heck, you could even replace the entire stylesheet with an alternative one. All of that and it doesn't require the user to hard refresh the page.
Here's a working example where I set the halloween theme to appear at exactly 8:30 AM. You'll see my standard dark theme have orange borders and my standard light theme have a light purple hue. This is a very rough first example, but I'm definitely going to sprinkle in a bunch of hidden things to appear throughout the year!
I don't believe you can update the entire site with a completely different "Gatsby Theme" because these are used during page generation, but it doesn't have to stop here. For more complex than styles, such as changing the functionality of a site, I recommend using
gatsby-browser.js. In the end, it's still React!
Also something great about using Gatsby Cloud, I was able to test this quickly without having to publish this live by simply creating a pull request which triggered a separate build for me and reports to the pull request if successful.