Rails 7: Bootstrap With Webpacker

Rails 7 no longer comes by default with Webpacker, the very common CSS and JS preprocessor that bridges Rails to the NPM + Node ecosystem of building apps with webpack.

However, if Webpack is your cup of tea, here’s how to bring it back into a Rails 7 app.

These instructions get you going with the popular Bootstrap library.

Make sure you have the Rails 7 gem:

% rails -v     
Rails 7.0.1         

Start with a new Rails 7 app:

rails new MyGreatApp --pre

Step 1: Remove ImportMap and replace it with Webpacker

  1. Add gem 'webpacker' to your Gemfile
  2. remove ‘importmap-rails gem from the Gemfile

Step 2: Enable Sass

Enable gem 'sassc-rails' in your Gemfile. Alternatively you can use sass-rails.

Step 3: Install Webpacker

run rails webpacker:install

In webpacker.yml change

source_path: app/javascript to source_path: app

extract_css: false to extract_css: true

Step 4: Create a New Pack, Import Bootstrap through Any File, and then SCSS Import Bootstrap

– create two new folders one inside the other at app/javascripts/packs
– make a new file in this folder app/javascripts/packs/application.js which contains imports for all of the CSS we want to use :

import '../stylesheets/require_something_else.scss'

This will be the primary manifest for our app. In app/views/layouts/application.html you will want to remove this line:

<%= javascript_importmap_tags %>

And replace it with:

<%= javascript_pack_tag 'application' %>

Step 5: Switch application.css to application.scss

Delete this file:

Now make a new empty file called application.scss in the same folder app/assets/

Step 6. Add Bootstrap gem

To Gemfile, add

gem 'bootstrap', '~> 5.1.3'

Also, in the application.scss file, add this:

@import "bootstrap";

Step 7. Add .scss to Asset Precompilation

Go to config/initializers/assets.rb

We want to uncomment and change this line:

Rails.application.config.assets.precompile += %w( application.scss )

Notice that we do not have to make any changes to our application.html.erb, which by default looks as below. This is handy and happens because the stylessheet_link_tag just references the stylesheet file without the extension type, which means it picks up the SCSS instead of the CSS file when we switched it from one to the other.

<!DOCTYPE html>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
    <%= javascript_importmap_tags %>

    <%= yield %>

No changes here.

Step 8. Make a Fake Articles Controller & Route

Create the articles controller with:

rails generate controller Articles

Add an empty def index to it:

class ArticlesController < ApplicationController
  def index

in config/routes.rb, uncomment this line:

root "articles#index"

And finally, create a Hello World file at app/views/articles/index.erb

Hello World!

Does it work?

Well, now you might hit an infamous Webpacker load problem that looks like this: