bin/rails generate turbo_overlay:install --theme tailwindThemes: plain (default), tailwind, bootstrap5, bootstrap3.
What the generator does:
- Chrome partials copied to
app/views/turbo_overlay/:_modal.html.erb,_drawer.html.erb,_popover.html.erb,_hint.html.erb, plus body-only_confirm.html.erband_loading.html.erb. These are your files — Tailwind and similar content scanners pick them up here automatically. Add_loading.html+<variant>.erbor_confirm.html+<variant>.erbfor chrome-specific markup. - Initializer at
config/initializers/turbo_overlay.rb. - Stack tag —
<%= overlay_stack_tag %>injected before</body>inapp/views/layouts/application.html.erb. - Importmap apps — appends
import { register } from "turbo_overlay"; register(application, { confirm: true })to your Stimulus entry (typicallyapp/javascript/controllers/index.js). The{ confirm: true }flag routesdata-turbo-confirmthrough the gem's themed dialog. - Propshaft apps — injects
stylesheet_link_tag "turbo_overlay"next to your existing one. - Sprockets apps — injects
*= require turbo_overlayinto your manifest CSS. - jsbundling / cssbundling apps — prints the snippet to add to your bundler entry. See bundling apps below.
Re-running is idempotent — anything already in place is left alone.
Pass --force to overwrite existing chrome partials when switching
themes:
bin/rails g turbo_overlay:install --theme tailwind --forceFlags for skipping pieces (use when you want to wire one step manually):
--skip-layout-inject— don't inject<%= overlay_stack_tag %>intoapplication.html.erb.--skip-javascript— don't append the Stimulus registration.--skip-stylesheet— don't wire the CSS link/import.--skip-chrome— don't copy chrome partials intoapp/views/turbo_overlay/.
If you skip the install generator entirely, the gem ships a plain
<dialog> chrome as a fallback — modals and drawers work, just
unstyled beyond the gem's CSS.
Include the concern:
class ApplicationController < ActionController::Base
include TurboOverlay::Controller
endIncluding the concern installs a layout proc that swaps to the
matching overlay layout on overlay requests. Plain turbo-frame
requests keep their turbo-rails layout.
The overlay layout replaces your application layout for overlay requests — only the view content is wrapped in the dialog/drawer/popover markup, not your nav, header, or footer.
For controllers with a custom layout method, call
turbo_overlay_layout from it — see the README.
jsbundling-rails (esbuild/rollup/webpack/bun) and cssbundling-rails apps have two paths:
-
Reference the gem in place. Add the gem's
app/javascriptand/orapp/assets/stylesheetsdirectories to your bundler's resolve paths, then:import { register } from "turbo_overlay" register(application)
@import "turbo_overlay";
-
Eject. Copy the gem's JS or CSS into your app and import locally:
bin/rails g turbo_overlay:eject --js bin/rails g turbo_overlay:eject --css bin/rails g turbo_overlay:eject --layouts
(Chrome partials are not part of eject — they're already in your app after
turbo_overlay:install.)Ejected files become yours; gem upgrades to those files no longer flow through.