If we’re building a Rails Engine and we’re using Importmap (instead of Webpacker or esbuild), here’s how we can connect our engine’s JavaScript, including Stimulus controllers to the main app:
Inside our engine (my_engine), create a folder like this:
app/javascript/my_engine/
├── application.js
└── controllers/
├── index.js
└── hello_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
console.log("Hello from MyEngine!")
}
}
In controllers/index.js, load our Stimulus controllers. We can do this with:
import { Application } from "@hotwired/stimulus"
import HelloController from "./hello_controller.js"
const app = Application.start()
app.register("hello", HelloController)
In our engine’s config (engine.rb):
initializer "my_engine.assets.precompile" do |app| app.config.assets.precompile += %w[my_engine/application.js] end
This makes sure Rails knows to include our engine’s JS when compiling assets.
In the host app’s config/importmap.rb, add:
pin "my_engine", to: "my_engine/application.js" we can also pin controller files if needed: pin_all_from "my_engine/controllers", under: "my_engine/controllers"
Now, in a view in our main app, we can use our engine’s Stimulus controller like this:
<div data-controller="hello">
Hello from the engine!
</div>
Tip: Let the Host App Start Stimulus (Optional)
If we want the host app to be in charge of starting Stimulus, skip starting it in the engine. Then in the host app’s application.js:
import { Application } from "@hotwired/stimulus"
import "my_engine/controllers"
const app = Application.start()
Work with our skilled Ruby on Rails developers to accelerate your project and boost its performance.
Hire Ruby on Rails Developer