Docs menu

Install StageWhisper in Ruby on Rails

In Ruby on Rails the StageWhisper loader has one natural home: your application layout’s <head>. One paste covers every page, the built-in CSP helpers hand the widget its nonce, and Turbo Drive needs no extra wiring.

Prerequisites

  • A StageWhisper site created in the dashboard.
  • Your app’s origin on the site’s origin allowlist — enable the localhost toggle for local testing.

Add the loader to your layout

  1. Copy the one-liner below and swap pub_your_site_key for the public site key shown on your site’s install page in the dashboard.
    Loader snippet
    <script async src="https://cdn.stagewhisper.co/loader.js" data-sw-key="pub_your_site_key"></script>
  2. Paste it into your application layout’s <head> (app/views/layouts/application.html.erb), just before the closing </head> tag:
    Layout excerpt
    <!-- app/views/layouts/application.html.erb -->
    <head>
      <title>MyApp</title>
      <%= csp_meta_tag %>
      <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
      <%= javascript_importmap_tags %>
    
      <script async src="https://cdn.stagewhisper.co/loader.js" data-sw-key="pub_your_site_key"></script>
    </head>
  3. Deploy. The tag is async, so it never blocks your page render — every page served through the layout now carries the widget.

Strict CSP: wire the nonce

Keep csp_meta_tag in your layout head — Rails’ default layout already renders it. When your content security policy carries a nonce, that helper emits it as meta[name="csp-nonce"], and the loader reads that value as a fallback and carries it through to the widget bundle. Alternatively, put the nonce attribute on the loader tag itself with content_security_policy_nonce:

Loader with explicit nonce
<script async src="https://cdn.stagewhisper.co/loader.js"
        data-sw-key="pub_your_site_key"
        nonce="<%= content_security_policy_nonce %>"></script>

Your own inline scripts can carry the same policy nonce by rendering them with javascript_tag nonce: true. For the exact directives to merge into your policy — and where the nonce goes in each install variant — see the Content Security Policy guide.

Turbo Drive

Nothing to do here. The loader lives in <head>, which Turbo Drive preserves across visits while it swaps the <body> — so the widget initializes once and stays mounted. No re-initialization, no turbo:load hooks; the widget re-evaluates your URL rules on every navigation by itself.

Verify

Refresh your app, then watch the site’s install status in the dashboard — it flips the moment the first ping arrives.

Widget not showing up? Head to Troubleshooting for the usual suspects — blocked origins, CSP, localhost, and stale config.