A lot of people have been having a hard time integrating bootstrap 5 in Rails 6 and since we have figured out a way to easily integrate the two we decided to put out this tutorial.
If you prefer the video tutorial:
We are going to show step by step using a newly created app, if you have an existing application you are trying to integrate into, the information below should still work just fine. We are also going to use MySQL as the default database so if you are using something else, then specify that connector instead.
Step 1 – Create a new Rails 6 application
rails new bootstrap5_base -d mysql
I don’t know why but sometimes even with a newly created application rails hangs when creating a controller, so lets update our binstubs before the next step.
rails app:update:bin
Step 2 – Create a new controller to test our integration
We are going to call our controller “welcome” and give it a default index action.
rails g controller welcome index
Now we are going to put some simple bootstrap stuff in our index file for testing
<!-- inside app/views/welcome/index.html.erb -->
<div class="collapse" id="navbarToggleExternalContent">
<div class="bg-dark p-4">
<h5 class="text-white h4">Collapsed content</h5>
<span class="text-muted">Toggleable via the navbar brand.</span>
</div>
</div>
<nav class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggleExternalContent" aria-controls="navbarToggleExternalContent" aria-expanded="false"
aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
</div>
</nav>
<main>
<section class="py-5 text-center container">
<div class="row py-lg-5">
<div class="col-lg-6 col-md-8 mx-auto">
<h1 class="fw-light">Album example</h1>
<p class="lead text-muted">Something short and leading about the collect ion below—its contents, the creator, etc. Make it short and sweet, but not too s hort so folks don’t simply skip over it entirely.</p>
<p>
<a href="#" class="btn btn-primary my-2">Main call to action</a>
<a href="#" class="btn btn-secondary my-2">Secondary action</a>
</p>
</div>
</div>
</section>
</main>
Next, we’re going to update our routes to make this the default / root view
config/routes.rb
Rails.application.routes.draw do
get 'welcome/index'
root 'welcome#index'
end
Step 3 – Create a new database and user for it and update your config
We created a MySQL db with the following details:
db name: bootstrap5_base_demo
username: bs5demo
password: bs5demo123
Then updated config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: bs5demo
password: bs5demo123
socket: /tmp/mysql.sock
development:
<<: *default
database: bootstrap5_base_demo
At this point we started the app on localhost:3000 just to make sure it was working… it was.
Step 4 – Install bootstrap and @popperJS using yarn
yarn add bootstrap @popperjs/core
Step 5 – Rename app/javascript directory and create some files
First we are going to rename app/javascript to app/frontend and update the source_path line in webpacker.yml to use the renamed directory
mv app/javascript app/frontend
In config/webpacker.yml change the source_path line to:
source_path: app/frontend ### this we changed from "app/javascript"
Now we are going to add a directory for our javascript files and create a couple files
mkdir app/frontend/js
touch app/frontend/js/bootstrap_js_files.js
touch app/frontend/packs/application.scss
Step 6 – Add our necessary imports
in app/frontend/js/bootstrap_js_files.js
import 'bootstrap/js/src/collapse'
import 'bootstrap/js/src/dropdown'
import 'bootstrap/js/src/scrollspy'
in app/frontend/packs/application.js
import '../js/bootstrap_js_files.js'
in app/frontend/packs/application.scss
// Import Bootstrap v5
@import "~bootstrap/scss/bootstrap";
Step 7 – Clear and recompile our assets and test our integration
rails assets:clobber
rails webpacker:compile
rails server
At this point you should have a working Rails 6 application with bootstrap 5 fully integrated.