Assets
app/js Modules
Keep application browser modules in app/js and load them through the generated importmap.
Keep source outside public files
Application JavaScript source lives under app/js:
app/js/app.js
app/js/controllers/hello_controller.js
Generated browser assets live under public files:
app/public/assets/importmap.json
app/public/assets/lazyshaft/
lazy js reads the source files, writes content-hashed public outputs, and
maps stable browser specifiers to those outputs.
Load the app entry
The layout inlines the importmap before importing the app module:
{{importmap "/assets/importmap.json"}}
<script type="module">import "/js/app.js"</script>
The generated importmap can map /js/app.js to a hashed lazyshaft file:
{
"imports": {
"/js/app.js": "/assets/lazyshaft/app/app-ZWUSRUPQ.js"
}
}
Templates keep using the stable /js/app.js specifier while browsers receive
the fingerprinted asset.
Import Turbo and Stimulus
The app entry may use GoLazy source directives:
// golazy:turbo
// golazy:stimulus
// golazy:turbo expands to:
import "@hotwired/turbo"
// golazy:stimulus imports Stimulus, starts the application, scans
app/js/controllers/**/*_controller.js, and registers each controller.
Add a Stimulus controller
Create a controller source file:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
this.element.dataset.ready = "true"
}
}
For this file:
app/js/controllers/hello_controller.js
GoLazy registers the identifier:
hello
Nested directories use --, and underscores in filenames become dashes.
Use lazy js for the manifest, library bundles, workers, copied assets, and generated outputs.