Rails 7 + bootstrap + getting first bootstrap example working is a little confusing

I’ve been reading about importMaps and rails 7 and decided to create first app and start a simple bootstrap example with rails 7. I could not

Here is the process.

$ rails new project
$ cd project
# create home controller and home view
$ bin/importmap pin bootstrap
# Select first bootstrap from https://getbootstrap.com/docs/5.1/components/toasts/#live-example
# The goal is to get this example working

Then I add to the application.js

$ subl app/javascript/application.js
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
// Here I add Toast just for the example
import { Toast } from 'bootstrap'
import "controllers"

Then I go to localhost:3000 and I see

<html>
  <head>
<style type="text/css">.turbo-progress-bar {
  position: fixed;
  display: block;
  top: 0;
  left: 0;
  height: 3px;
  background: #0076ff;
  z-index: 9999;
  transition:
    width 300ms ease-out,
    opacity 150ms 150ms ease-in;
  transform: translate3d(0, 0, 0);
}
</style>
    <title>Rails7project2</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="csrf-param" content="authenticity_token">
<meta name="csrf-token" content="M7WXSkSRpuT9Nq6kJNGdzyxPxLQV__czRLEW9PdeCbWmkLvpoonAYNZ1pT6BKQ1PFAlOwgSJawAEJdotWVybIA">
    

    <link rel="stylesheet" href="/assets/application-e0cf9d8fcb18bf7f909d8d91a5e78499f82ac29523d475bf3a9ab265d5e2b451.css" data-turbo-track="reload">
    <script type="importmap" data-turbo-track="reload">{
  "imports": {
    "application": "/assets/application-ddfe7a679d279db82d236a96ed63ad21b88239bbd83224d2ff86043c3eb67c74.js",
    "@hotwired/turbo-rails": "/assets/turbo.min-305f0d205866ac9fc3667580728220ae0c3b499e5f15df7c4daaeee4d03b5ac1.js",
    "@hotwired/stimulus": "/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js",
    "@hotwired/stimulus-loading": "/assets/stimulus-loading-685d40a0b68f785d3cdbab1c0f3575320497462e335c4a63b8de40a355d883c0.js",
    "bootstrap": "https://ga.jspm.io/npm:bootstrap@5.1.3/dist/js/bootstrap.esm.js",
    "@popperjs/core": "https://ga.jspm.io/npm:@popperjs/core@2.11.2/lib/index.js",
    "controllers": "/assets/controllers/index-2db729dddcc5b979110e98de4b6720f83f91a123172e87281d5a58410fc43806.js",
    "controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
    "controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js"
  }
}</script>
<link rel="modulepreload" href="/assets/application-ddfe7a679d279db82d236a96ed63ad21b88239bbd83224d2ff86043c3eb67c74.js">
<link rel="modulepreload" href="/assets/turbo.min-305f0d205866ac9fc3667580728220ae0c3b499e5f15df7c4daaeee4d03b5ac1.js">
<link rel="modulepreload" href="/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js">
<link rel="modulepreload" href="/assets/stimulus-loading-685d40a0b68f785d3cdbab1c0f3575320497462e335c4a63b8de40a355d883c0.js">
<script src="/assets/es-module-shims.min-6982885c6ce151b17d1d2841985042ce58e1b94af5dc14ab8268b3d02e7de3d6.js" async="async" data-turbo-track="reload"></script>
<script type="module">import "application"</script>
  </head>

  <body>
    <h1>Page</h1>

<button type="button" class="btn btn-primary" id="liveToastBtn">Show live toast</button>

<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
  <div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
    <div class="toast-header">
      <strong class="me-auto">Bootstrap</strong>
      <small>11 mins ago</small>
      <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
    </div>
    <div class="toast-body">
      Hello, world! This is a toast message.
    </div>
  </div>
</div>

<script>
  var toastTrigger = document.getElementById('liveToastBtn')
  var toastLiveExample = document.getElementById('liveToast')
  if (toastTrigger) {
    toastTrigger.addEventListener('click', function () {
      var toast = new Toast(toastLiveExample)

      toast.show()
    })
  }
</script>
  

</body></html>

An error occurs when selecting the button

(index):55 Uncaught ReferenceError: Toast is not defined
    at HTMLButtonElement.<anonymous> ((index):55)

Same is for new bootstrap.Toast

(index):55 Uncaught ReferenceError: bootstrap is not defined
    at HTMLButtonElement.<anonymous> ((index):55)

What is missing? I guess there has to be a stimulus controller here for the click otherwise we can not use bootstrap, right?

Update: I did create a stimulus controller for the click

import { Controller } from "@hotwired/stimulus"
import { Toast } from "bootstrap"

export default class extends Controller {

  show() {
    const toastLiveExample = document.getElementById('liveToast')
    const toast = new Toast(toastLiveExample)
    toast.show()
  }
};

toast still does not show.

Just ran into the same thing last week. Basically the items you import in application.js are not visible in the .erb

To make them available you need to write something like

window.Toast = Toast();

also can using cssbuilding

Yes they are not, Kind of confusing, i knew they are not, but could not find a guide that mentions it. I wanted to help a developer in our team with this and found it difficult to point them to a good documentation. It is all experience

You can, you can. You are right. It’s a little confusing when you step into a “new with rails” developer shoes and look it from their perspective.