There is an easy way to add Bootstrap while creating an app using the Rails Command Line but here I have shown how to add them manually. In addition to adding Bootstrap 5 and Font Awesome 6 to our Rails 7 app, we will be adding JQuery, custom scss (custom.scss) and custom javascript (my_script.js) to the Rails 7 app.
Version
- ruby 3.1.2
- Rails 7.0.3.1
- Bootstrap 5.2.0
- Font Awesome 6.1.2
Instructions
- In the Gemfile add:
gem "sassc-rails"
gem "bootstrap", "~> 5.2.0"
gem "jquery-rails"
Remember to bundle install
in terminal before proceeding.
- In terminal, (1) add Font Awesome, (2) Rename application.css to application.scss, (3) create custom.scss (4) create my_script.js:
$ bin/importmap pin @fortawesome/fontawesome-free
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
$ touch app/assets/stylesheets/custom.scss
$ touch app/javascript/my_script.js
Remove all the *= require and *= require_tree statements from application.scss
- In
app/assets/stylesheets/application.scss
import bootstrap and custom.scss:
// Custom bootstrap variables must be set or imported *before* bootstrap.
@import "bootstrap";
@import "custom";
- Enable Inline Source Maps in
config/environments/development.rb
:
config.sass.inline_source_maps = true
To properly enable it, clear your asset cache and restart the rails server:
$ rm -r tmp/cache/assets
- In
config/importmap.rb
:
# From "jquery-rails" gem
pin "jquery", to: "jquery3.min.js", preload: true
pin "jquery_ujs", to: "jquery_ujs.js", preload: true
# From "bootstrap" gem
pin "bootstrap", to: "bootstrap.min.js", preload: true
pin "@popperjs/core", to: "popper.js", preload: true
# Use all.js instead of fontawesome.js
pin "@fortawesome/fontawesome-free", to: "https://ga.jspm.io/npm:@fortawesome/fontawesome-free@6.1.2/js/all.js"
# Custom JS
pin "my_script", to: "my_script.js", preload: true
- In
config/initializers/assets.rb
(add js files that came with the gem):
Rails.application.config.assets.precompile += %w( jquery3.min.js jquery_ujs.js bootstrap.min.js popper.js )
- In
application.js
:
import "jquery";
import "jquery_ujs";
import "@popperjs/core";
import "bootstrap";
import "@fortawesome/fontawesome-free";
import "my_script";
- In
custom.scss
:
body {
background-color: #888;
}
In my_script.js
:
// Test if jquery is loaded by typing $.fn.jquery in the console as per
// https://stackoverflow.com/questions/6973941/how-to-check-what-version-of-jquery-is-loaded/26674265#26674265
// This function runs on every page "load"
document.addEventListener("turbo:load", () => {
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
const popoverList = [...popoverTriggerList].map((popoverTriggerEl) => new bootstrap.Popover(popoverTriggerEl));
});
Important Note
- The only time you need to add to
config.assets.precompile
inassets.rb
is when you want to add JavaScript from a gem. In other words when using./bin/importmap pin
command to add JavaScript files, you do not need to add anything inassets.rb
- Any time you have a custom JavaScript file, you have to include it in importmap.rb. For e.g. add line:
pin "my_script", to: "my_script.js", preload: true
to importmap.rb and add lineimport "my_script.js"
to application.js. If you add custom JavaScript files in your application.js file and not in importmap.rb, your app may function in development mode but in production mode your JavaScript files will not get loaded.
Testing to see if Bootstrap and JS work as expected
- Create home controller with index action
$ rails g controller home index
- Add Bootstrap modal component in
app/views/home/index.html.erb
:
<div class="container">
<div class="row">
<div class="col-md-4 mt-4">
<i class="fa-solid fa-house fa-2xl mx-3"></i>
<i class="fa-solid fa-plane fa-2xl mx-3"></i>
<i class="fa-solid fa-martini-glass fa-2xl mx-3"></i>
</div>
<div class="col-md-8 mt-4">
<button type="button" class="btn btn-lg btn-danger" data-bs-toggle="popover" data-bs-title="Popover title" data-bs-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>
</div>
</div>
<div class="row mt-4">
<div class="col-md-8">
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Top popover">
Popover on top
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Right popover">
Popover on right
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Bottom popover">
Popover on bottom
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Left popover">
Popover on left
</button>
</div>
</div>
</div>
- Go to http://localhost:3000. You should see popovers by clicking any button (Bootstrap and my_script.js in action). The background must be grey (set by custom.scss). You must see 3 icons: Home, Plane and Martini. Open up the web browser console and type:
$.fn.jquery
It should return the version of jQuery which is 3.6.0 at the time of writing this document.
Link to example app: https://github.com/overdrivemachines/bootstrap-rails7
Top comments (1)
Cool