TIL: Using ActiveAdmin with importmap-rails

Henrik Hauge Bjørnskov
2 min readMar 30, 2023

--

Some of you might be thinking: Why?

Well I believe having less dependencies in my Rails applications is a good thing. Especially if those dependencies are in a another language and requires an additional dependency install. And since we are using Ruby and Rails I would be thrilled to get rid of node and package.json in my project.

The benefit here, is that we don’t need to compile anything and that most browsers just works out the box.

There are actually two ways to do this. Either by using importmaps or by using a CDN directly with config.register_javascript . The latter is probably the easiest.

Using a CDN directly

This is the easiest and most straightforward way of doing it. It requires you to have config.use_webpacker = false then use config.clear_javascripts! to make sure we don’t load the default javascript for ActiveAdmin.

Combining the above we get a config/initializers/active_admin.rb file with the following:

ActiveAdmin.setup do |config|
# your other config stuff goes here...

# clear any previous assets
config.clear_javascripts!

# We need jQuery and jQuery UI and jQuery-ujs which are dependencies
config.register_javascript "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.js"
config.register_javascript "https://cdn.jsdelivr.net/npm/jquery-ujs@1.2.3/src/rails.min.js"
config.register_javascript "https://cdn.jsdelivr.net/npm/jquery-ui@1.13.2/dist/jquery-ui.min.js"

# The actual active admin javascript file
config.register_javascript "https://cdn.jsdelivr.net/npm/@activeadmin/activeadmin@2.13.1/app/assets/javascripts/active_admin/base.min.js"
end

Restart Puma and voila! 🚀

Using importmap-rails

This requires tweaking ActiveAdmin a little bit. But otherwise it is fairly straight forward.

We start with doing config.clear_javascripts! in config/initializers/active_admin.rb . Just like before but we also have to add the script tags for importmaps to the ActiveAdmin layout.

This is done by creating a module and prepending it to ActiveAdmin::Views::Pages::Base and overriding build_active_admin_head and using super to retain the orignal implementation. I just put it all in the initializer like so

ActiveAdmin.setup do |config|
# ... any previous configuration goes here

# clear previous asset for javascript to make the asset pipeline
# happy
config.clear_javascripts!
end

module ActiveAdmin
module Views
module Head
def build_active_admin_head
within super do
text_node javascript_importmap_tags("active_admin")
end
end
end
end
end

ActiveAdmin::Views::Pages::Base.send :prepend, ActiveAdmin::Views::Head

The in my config/importmap.rb I have pinned the modules we need and using the same urls are before

# The entrypoint
pin "active_admin", preload: true

# ActiveAdmin and dependencies
pin "@activeadmin/activeadmin", to: "https://cdn.jsdelivr.net/npm/@activeadmin/activeadmin@2.13.1/app/assets/javascripts/active_admin/base.min.js"
pin "jquery", to: "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.js"
pin "jquery-ui", to: "https://cdn.jsdelivr.net/npm/jquery-ui@1.13.2/dist/jquery-ui.min.js"
pin "jquery-ujs", to: "https://cdn.jsdelivr.net/npm/jquery-ujs@1.2.3/src/rails.min.js"

The entrypoint app/javascript/active_admin.jsfile just the modules needed for activeadmin

import 'jquery'
import 'jquery-ui'
import 'jquery-ujs'
import '@activeadmin/activeadmin'

Restart Puma and voila! 👏

Whats the better approach?

It depends. The CDN approach is way simpler than the importmaps but it has some negatives. You have to always trust the CDN will never go down or the assets be removed.

The importmaps method is more complex but can use local files. So the pinned assets can be downloaded into vendor/javascript and that will ensure your assets are always present.

--

--

Henrik Hauge Bjørnskov

I build stuff at Relatel A/S, vivid traveller and gear junkie.