Add Bootstrap 5 and Font Awesome 6 to Rails 7
Tags: rails, javascript, bootstrap, fontawesome
Published: 2022-08-03 17:08:00


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6kkviffi0a9nf8uq4ou.png)

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:
```rb
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:
```sh
$ 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:
```scss
// Custom bootstrap variables must be set or imported *before* bootstrap.
@import "bootstrap";
@import "custom";
```

- Enable Inline Source Maps in `config/environments/development.rb`:
```rb
config.sass.inline_source_maps = true
```
To properly enable it, clear your asset cache and restart the rails server:
```sh
$ rm -r tmp/cache/assets
```

- In `config/importmap.rb`:
```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):
```rb
Rails.application.config.assets.precompile += %w( jquery3.min.js jquery_ujs.js bootstrap.min.js popper.js )
```

- In `application.js`:
```js
import "jquery";
import "jquery_ujs";
import "@popperjs/core";
import "bootstrap";
import "@fortawesome/fontawesome-free";
import "my_script";
```

- In `custom.scss`:
```css
body {
  background-color: #888;
}
```

In `my_script.js`:
```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` in `assets.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 in `assets.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 line `import "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`:
```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:
```js
$.fn.jquery
```
It should return the version of jQuery which is 3.6.0 at the time of writing this document.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqn4fxdej3uqu32k3c1w.png)

Link to example app: https://github.com/overdrivemachines/bootstrap-rails7