DEV Community

Rails 7, Bootstrap 5 and importmaps without nodejs

Alessandro Rodi on January 12, 2022

Our goal: remove nodejs As many other people in the Rails community, I started setting up brand new Rails 7 projects, and I need to re-l...
Collapse
 
hashmaster3k profile image
Hashim G

Great write up Alessandro. What I don't understand is if import maps loads libraries via CDN, why is the Bootstrap gem still needed? You could load Bootstrap straight into the header without all this hassle.

Collapse
 
coorasse profile image
Alessandro Rodi

Hi Hashim,
yes, correct. You could load Bootstrap Javascript part through CDN, but you would still need the gem to use the SCSS stylesheets and customise it. Now, since you have the gem, I think is wise to use also the JS wrapped within the gem, so that you don't risk having divergent versions (one from CDN and one from the Gem).
Of course, if you don't need to customise bootstrap, then you can load everything from CDN.

Collapse
 
panikos profile image
Panayiotis

Excellent and helpful article. Thanks Alessandro

Collapse
 
indikaimk profile image
indikaimk

Tried the whole day to get Bootstrap working with Rails 7.
This method works awesome.

Collapse
 
mtnbiker profile image
Greg S

Thank you. Clears up a lot of confusion. The dependancies and/or defaults of the Rails 7 options aren't clear.

Another confusion for me. Is Sprockets the way forward or?

Probably would help if you showed all your changed or added code. Would help avoid the confusion @ochupa faced.

Collapse
 
skrobul profile image
Marek Skrobacki

Don't think this really "works without node" - bootstrap gem does not work if there is no execjs runtime (just try removing executable permission from your NodeJS installation on the system) because autoprefixer needs it. Is there some magic way to force it to use something else?

Collapse
 
coorasse profile image
Alessandro Rodi

Good point! Yes, you can also use another runtime: github.com/ai/autoprefixer-rails#u...

Collapse
 
kisp_1 profile image
Kilian Sprotte

I am also running into this problem with execjs.

I was hoping to set things up so that node is only needed in development, but not in production.

I would then have a two-stage Dockerfile where the assets precompile run is done with node present, but then node should not be needed.

Unfortunately, the execjs error about missing node prevents me from opening a rails console or running db:migrate.

I haven't managed to make this work using groups or require: false in my Gemfile.

Collapse
 
duarme profile image
Duccio Armenise

Thanks bro.

Collapse
 
henryxz profile image
Hernaldo Jesus Henriquez Nuñez • Edited

Hi, I tried this but the CSS is not working. I get this error from the browser console:

The stylesheet localhost:3000/assets/bootstrap was not loaded because its MIME type, “application/javascript”, is not “text/css”.
Uncaught TypeError: Error resolving module specifier “application”. Relative module specifiers must start with “./”, “../” or “/”.
^^ Module TypeError above is polyfilled and can be ignored ^^ es-module-shims.js:34:12

Collapse
 
henryxz profile image
Hernaldo Jesus Henriquez Nuñez

seems like the @import "bootstrap" call inside application.css is importing the bootstrap javascript, because in Style editor of Firefox, I see a bootstrap file that is just javascript

Collapse
 
henryxz profile image
Hernaldo Jesus Henriquez Nuñez

ok, seems like I needed to rename "application.css" to "application.scss"

Collapse
 
jmschp profile image
Miguel Hargreaves Pimenta • Edited

Hey!

I think this could be made simpler.
I believe the bootstrap-rubygem already injects in the assets throughs sprockets the bootstrap.min.js and SCSS files, and also the poper.js through the dependency popper_js-rubygem.

So, in terms of the JS files, all we need to do, after bundeling the bootstrap-rubygem, is import them in the application.js

import "./popper";
import "./bootstrap.min";
Enter fullscreen mode Exit fullscreen mode

I have this working in development.

Collapse
 
jusko profile image
jusko

Thanks. This is simpler.

Collapse
 
linediconsine profile image
Marco A.

In application.js :

import "popper"
import "bootstrap"
Enter fullscreen mode Exit fullscreen mode

give this error for me on browser :

GET http://127.0.0.1:3000/assets/popper net::ERR_ABORTED 404 (Not Found)

GET http://127.0.0.1:3000/assets/bootstrap net::ERR_ABORTED 404 (Not Found)

Enter fullscreen mode Exit fullscreen mode

full error log:

GET http://127.0.0.1:3000/assets/bootstrap net::ERR_ABORTED 404 (Not Found)
VM167 application-afa54e21226316d7c1dc5bb51d77586423db47a2adf4ce6a3fc09888e5eda505.js:2 Uncaught SyntaxError: Cannot use import statement outside a module (at VM167 application-afa54e21226316d7c1dc5bb51d77586423db47a2adf4ce6a3fc09888e5eda505.js:2:1)
application-afa54e21226316d7c1dc5bb51d77586423db47a2adf4ce6a3fc09888e5eda505.js:2 Uncaught SyntaxError: Cannot use import statement outside a module (at application-afa54e21226316d7c1dc5bb51d77586423db47a2adf4ce6a3fc09888e5eda505.js:2:1)
application-afa54e21226316d7c1dc5bb51d77586423db47a2adf4ce6a3fc09888e5eda505.js:2          GET http://127.0.0.1:3000/assets/popper net::ERR_ABORTED 404 (Not Found)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
linediconsine profile image
Marco A.

I miss the

bundle add bootstrap

Collapse
 
danchenkov profile image
Alexei Danchenkov • Edited

This is a pretty neat solution, all work is done by Sprockets as intended. No Node, no Foreman, great.

However, enabling sassc-rails in Gemfile brings in embedded sassc, based on now deprecated libsass v3.5 which does not handle modern Sass. So no @use directives, no color functions like color.adjust, etc., and one gets errors like: SassC::SyntaxError: Error: Function hsl is missing argument $saturation. (that is if color variables are defined in modern format — without commas, e.g. $body-text-color: hsl(0deg 0% 20%)).

Is there a way to integrate Dart Sass into Sprockets or I am missing something?

Collapse
 
ochupa profile image
ochupa • Edited

Hey Alessandro, I'm trying to add 'bootstrap-rails' gem but getting error - Could not find gem 'bootstrap-rails' in rubygems repository rubygems.org/ or installed locally.
Could help with the proper name of bootstrap gem?

Collapse
 
janisleuenberger profile image
Janis Leuenberger

I think he is talking about github.com/twbs/bootstrap-rubygem. Therefore the gem name is just 'bootstrap'.
Correct me if I'm wrong.

Collapse
 
jusko profile image
jusko

Thanks for a helpful, concise post.

  • Can confirm this comment to be correct and didn't need precompile the javascripts in config/initializers/assets.rb.
  • As I'm stuck on Bootstrap 4, I experienced problems with jquery and also struggled to get the popper.js bundled with the bootstrap (@4.5) gem to work.

  • Solved using the following pins (the CDN for jquery is important as mentioned on SO above):

pin 'jquery', to: 'https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.js', preload: true
pin 'popper.js', to: 'https://ga.jspm.io/npm:popper.js@1.16.1/dist/umd/popper.js', preload: true
Enter fullscreen mode Exit fullscreen mode
Collapse
 
matiasalbarello profile image
Matias Albarello

First of all, thanks Alessandro. It's clear and gets direct to the point. Unfortunately, I couldn't make it work. I created a new project to test this out and followed exactly the steps described here. After that, I've added a simple navbar from Bootstrap examples, that contains a dropdown (making it need bootstrap.js). The styles look good but the dropdown doesn't work. Here the repo if anybody wants to take a look and have an idea on what's wrong: github.com/matiasalbarello/test-im...
If anybody has a working example would be great! Please share if so :)

Collapse
 
matiasalbarello profile image
Matias Albarello

In case it helps someone: I was using the wrong navbar example from bootstrap page (using from version 4 instead of 5). Also found that these steps are followed in this app template: railsbytes.com/public/templates/V2...

Collapse
 
josephmo_91 profile image
Joseph Mouhanna • Edited

The initial tutorial works fine. However, if I copy the application to another folder, and delete all the parts that normally do not make it into GitHub (using a rails .gitignorefile), then run: bundle install, followed by a rails s command, then go to 127.0.0.1:3000/, I get the following error:

Showing /Users/joseph-mac/ProxLearn/Development/PLIConnectV2/repositories/pli2-no-node/app/views/layouts/application.html.slim where line # raised:

link_tree argument must be a directory
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js

Collapse
 
jepzen profile image
Jeppe B. Svendsen

Nice. I had to run the rails assets:precompile after adding javascript part as well to get it to work.

Question: Can i just rename the 'application.css' to 'application.scss' (I did and it seems ok but should i think of anything else when doing so?)

Collapse
 
chmich profile image
Christian Sedlmair

Questions: Importmap does not bundle or build compiled javascript, thus, jsx, by example, is not working. Until now i havent used react in rails, for my current needs it would be enough, but the day may come.

As i understood, you have to decide which rail you choose: you cannot use importmap and add Shakapacker or jsbundling later for using it alongside importmap.

How do you think?

Collapse
 
eliblocks profile image
Eli Block • Edited

Thanks for the guide! I believe it should be

pin "@popperjs/core", to: 'popper.js', preload: true
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jmschp profile image
Miguel Hargreaves Pimenta

Actually it's not. The bootstrap gem dependes on the popper_js gem

Bootstrap tooltips and popovers depend on popper.js for positioning. The bootstrap gem already depends on the popper_js gem.

Collapse
 
ethand91 profile image
Ethan

Thanks for this, bookmarking for future reference. :)

Collapse
 
wafcio profile image
Krzysztof Wawer

There should be bootstrap gem instead of bootstrap-rails gem

Collapse
 
zicrou profile image
Abdou Aziz Seck

Still Very Helpfull, Thank you Sir!

Collapse
 
minhtoandev profile image
Minh Toàn

Helpful

Collapse
 
rgaufman profile image
Roman Gaufman

This is great, but rails g scaffold doesn't use bootstrap templates which is a bit annoying, any solution to that?

Collapse
 
akontopoulos profile image
a-kontopoulos

popper.js is not running when I install Bootstrap with this method. However bootstrap.js is working. Any ideas why?

Collapse
 
coorasse profile image
Alessandro Rodi

too few details, sorry. I'd suggest opeining a question on stackoverflow with more details.

Collapse
 
zhenyat profile image
ZT

Thx Alessandro! Following your approach I have added Simple Form:
gem 'simple_form'
and run the command:
bin/rails generate simple_form:install --bootstrap
It works fine.