Search code examples
ruby-on-railsbootstrap-modalbootstrap-5ruby-on-rails-7stimulusjs

Rails 7 and Bootstrap error in stimulus - failed to resolve module specifier bootstrap


I am following this tutorial: https://www.hotrails.dev/articles/rails-modals-with-hotwireEverything goes well until I create this stimulus controller file:

import { Controller } from "@hotwired/stimulus"
import * as bootstrap from "bootstrap"

export default class extends Controller {
  connect() {
    this.modal = new bootstrap.Modal(this.element)
  }

  open() {
    if (!this.modal.isOpened) {
      this.modal.show()
    }
  }

  close(event) {
    if (event.detail.success) {
      this.modal.hide()
    }
  }
}

I am getting this error:

"Failed to register controller: modal (controllers/modal_controller) TypeError: Failed to resolve module specifier "bootstrap". Relative references must start with either "/", "./", or "../"."

More info: I have a bootstrap gem in gemfile, bootstrap CSS classes are accessible and available. But bootstrap js is not available and I dont know how to make it available to my Rails 7 app.

Also, I saw somewhere that I have to update the application.js file by adding these two last lines for bootstrap, and I would like to check with you if it is correct:

import "@hotwired/turbo-rails"
import "controllers" 
import * as bootstrap from "bootstrap" 
window.bootstrap = bootstrap;

How do I make Bootstrap JS also available in my Rails 7 app?

Thank you

Update:

I also did the following:

npm install bootstrap

I updated the app/javascript/application.js file:

import "@hotwired/turbo-rails"
import "controllers"
import "bootstrap"

import * as bootstrap from "bootstrap"

window.bootstrap = bootstrap;

and importmap.rb file:

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"

pin "bootstrap", to: "bootstrap/dist/js/bootstrap.bundle.min.js", preload: true

But I am still not getting the Bootstrap JS loaded into my app, and I am still getting the same error in Console: items:1 Uncaught TypeError: Failed to resolve module specifier "bootstrap". Relative references must start with either "/", "./", or "../".


Solution

  • Rails uses importmaps by default, it doesn't use node_modules to find packages:

    # config/importmap.rb
    
    pin "bootstrap", to: "https://ga.jspm.io/npm:[email protected]/dist/js/bootstrap.esm.js"
    pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/[email protected]/lib/index.js"
    

    or just use an importmap command:

    $ bin/importmap pin bootstrap
    
    import * as bootstrap from "bootstrap"
    
    // or just get what you need
    import { Modal } from "bootstrap"
    

    https://github.com/rails/importmap-rails