> ## Documentation Index
> Fetch the complete documentation index at: https://rollout.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Ruby on Rails

## Step 1: Create View Template

Add a container element in your ERB template:

```xml theme={null}
<!-- app/views/your_controller/index.html.erb -->
<h1>Your Application</h1>
<div id="rollout-container"></div>
```

## Step 2: Add JavaScript Initialization

Create a JavaScript file or add to your existing pack:

```javascript theme={null}
// app/javascript/packs/rollout.js
document.addEventListener('DOMContentLoaded', function() {
  const container = document.getElementById('rollout-container');
  
  // Fetch token from Rails backend
  fetch('/rollout-token', {
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-Token': document.querySelector("[name='csrf-token']").content
    }
  })
  .then(response => response.json())
  .then(data => {
    const token = data.token;
    
    // Add required styles
    const styleLink = document.createElement('link');
    styleLink.rel = 'stylesheet';
    styleLink.href = 'https://esm.sh/@rollout/link-react@latest/dist/style.css';
    document.body.appendChild(styleLink);

    // Dynamically load Rollout bundle
    import(/* webpackIgnore: true */ 'https://esm.sh/@rollout/link-react@latest?bundle=all').then(
      ({ RolloutLinkProvider, CredentialsManager, createElement, createRoot }) => {
        const root = createRoot(container);
        
        root.render(
          createElement(
            RolloutLinkProvider,
            { token },
            createElement(CredentialsManager)
          )
        );
      }
    );
  });
});
```

## Step 3: Add Rails Route

Create a route to handle token generation:

```ruby theme={null}
# config/routes.rb
get '/rollout-token', to: 'rollout#generate_token'
```

## Step 4: Create Controller

Implement token generation in a controller:

```ruby theme={null}
# app/controllers/rollout_controller.rb
class RolloutController < ApplicationController
  def generate_token
    # Implement your actual token generation logic here
    # This should use your ROLLOUT_CLIENT_SECRET
    
    render json: {
      token: generate_secure_token # Replace with actual token generation
    }
  end

  private

  def generate_token(user_id)
   now = Time.now.to_i
 
   JWT.encode({
     iss: ENV['ROLLOUT_CLIENT_ID'],
     sub: user_id,
     iat: now,
     exp: now + 900  # 15 minutes
   },
   ENV['ROLLOUT_CLIENT_SECRET'],
   'HS512')
  end
end
```

## Step 5 (Optional): Handle Credential Events

Add event handling in the JavaScript:

```javascript theme={null}
// Update the import block
.then(({ RolloutLinkProvider, CredentialsManager, createElement, createRoot }) => {
  const handleCredentialAdded = ({ id, appKey }) => {
    console.log(`New credential added - ID: ${id}, App: ${appKey}`);
    
    // Send to Rails backend
    fetch('/store-credential', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': document.querySelector("[name='csrf-token']").content
      },
      body: JSON.stringify({
        credential_id: id,
        app_key: appKey
      })
    });
  };

  const root = createRoot(container);
  root.render(
    createElement(
      RolloutLinkProvider,
      { token },
      createElement(CredentialsManager, {
        onCredentialAdded: handleCredentialAdded
      })
    )
  );
});
```

## Step 6: Update CSP

Update `config/initializers/content_security_policy.rb`:

```ruby theme={null}
# config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy do |policy|
  policy.default_src :self
  policy.font_src    :self, :data
  policy.img_src     :self, :data
  policy.object_src  :none
  
  # Allow esm.sh for scripts and styles
  policy.script_src  :self, :unsafe_eval, :unsafe_inline, 'https://esm.sh'
  policy.style_src   :self, :unsafe_inline, 'https://esm.sh'
  
  # Allow connecting to your backend and Rollout's API
  policy.connect_src :self, 'https://universal.rollout.com'
  
  # If you're using webpack-dev-server in development
  if Rails.env.development?
    policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035", 'https://universal.rollout.com'
  end

  policy.worker_src  :self
end
```

### Alternative to CSP

You can also use nonces or hashes for better security, but that's more complex to set up with dynamic imports. If you want to go that route, you'd need to:

```ruby theme={null}
rubyCopyRails.application.config.content_security_policy do |policy|
  policy.script_src :self, :unsafe_eval, 'https://esm.sh' do |source|
    source.nonce :script
  end
end
```

And then update your JavaScript to include the nonce:

```javascript theme={null}
<script nonce="<%= request.content_security_policy_nonce %>">
  // Your code here
</script>
```
