Multiple Bootstrap4 Themes with Webpacker05 Mar 2019
The goal of this post is to share a flexible way of supporting multiple Bootstrap4 themes, using webpacker. If you hate reading blog posts or just want to jump straight in to the code, I’ve created a demo app you can pull from Github here.
From Sprockets to Webpacker
Recently I began the process of migrating a Rails app from sprockets to webpacker. I hit many snags along the way, but one of the most awkward ones was supporting multiple themes. The Rails application I was working on had a “default” theme and a “dark” theme. Both were compiled and served with some “Rails magic” and I did’nt really have to worry too much about how sprockets worked behind the scenes. As the application grew, our dev team decided to move to webpacker, so we could take advantage of JS libraries like React. I figured that since Bootstrap 4 uses SCSS and variable overriding, it’d be a pretty simple aspect of the migration. Needless to say I was wrong.
So here we’re telling our application to use the webpacker helpers:
stylesheet_pack_tag to load our assets or ‘packs’.
current_theme variable needs to return a theme string, for example:
'darkly'. This will be the name of our theme’s pack.
A good idea for
current_theme is to add a string column to your uses table called ‘theme’, where users theme selection can be saved.
Then write a UserHelper method to access this in the view for the current_user.
In the demo app I’ve just stored the variable as a simple cookie.
The next place we need to look is
So what does that mean? Basically everything that you want webpacker to compile must be imported here, this is fairly new to sprockets veterans.
application.js I’m importing some standard libraries like bootstrap, then I’m importing all of my themes.
Structure is Key
An important thing to note here is my directory structure, it’s very important to keep your packs clearly separated from an early stage.
This will allow us to dynamically request a specific theme in our view code.
Lets focus on the theme
Then in our cerulean.scss file we can import our custom theme variables, bootstrap and any other styles needed for our theme.
The most important thing to note here is the order of the imports. Here we take advantage of Bootstrap4 using SCSS, by importing our variables first to overwrite the bootstrap default variables.
This is what allows us to have custom colors, fonts etc.
Creating your own theme
As you can see the rest of our theme’s packs have exactly the same structure and exactly the same importing strategy. This gives us a consistent and predictable folder structure for our code, but also allows fully flexible theming. With this approach you can add a new theme in minutes!
So now all you have to do is create a
_variables.scss and override bootstrap to your liking.
If you’re like me and don’t have time to come up with a totally unique theme by yourself there’s lots of places online where you can buy themes, or just download free ones.
For my demo app, I used BootSwatch themes, you should check them out for ideas and color schemes.