Rehearsals

Implementation Examples

Real-world examples of Rehearsals implementations across different platforms and use cases.

Basic HTML Website

Simple implementation for static HTML sites.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Website</title>
  
  <!-- Rehearsals Installation -->
  <script>
    window.deepPredictionSettings = {
      apiKey: 'dp_proj_xxxxx',
      organizationId: 'dp_org_xxxxx'
    };
  </script>
  <script src="https://app.runrehearsals.com/recorder.js" async></script>
  
  <!-- Rest of your head content -->
</head>
<body>
  <h1>Welcome to My Site</h1>
  
  <!-- Privacy-conscious form -->
  <form id="contact-form">
    <input type="text" name="name" placeholder="Name">
    <input type="email" name="email" placeholder="Email">
    <input type="password" name="password" placeholder="Password">
    <input type="text" name="ssn" class="rh-mask-text" placeholder="SSN">
    <button type="submit">Submit</button>
  </form>
  
  <script>
    // Track form submission
    document.getElementById('contact-form').addEventListener('submit', (e) => {
      e.preventDefault();
      window.rehearsals?.trackEvent('form_submitted', {
        formId: 'contact-form'
      });
    });
  </script>
</body>
</html>

React Application

App.jsx

import React, { useEffect } from 'react';
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';

// Rehearsals hook for route tracking
function useRehearsals() {
  const location = useLocation();
  
  useEffect(() => {
    // Track page views on route change
    window.rehearsals?.trackPageView({
      url: location.pathname,
      search: location.search
    });
  }, [location]);
}

// Initialize Rehearsals
function RehearsalsProvider({ children }) {
  useEffect(() => {
    // Configure
    window.deepPredictionSettings = {
      apiKey: process.env.REACT_APP_REHEARSALS_API_KEY,
      organizationId: process.env.REACT_APP_REHEARSALS_ORG_ID
    };
    
    // Load script
    const script = document.createElement('script');
    script.src = 'https://app.runrehearsals.com/recorder.js';
    script.async = true;
    document.head.appendChild(script);
    
    return () => {
      // Cleanup
      window.rehearsals?.destroy();
      document.head.removeChild(script);
    };
  }, []);
  
  return children;
}

// Main App
function App() {
  useRehearsals();
  
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/products" element={<Products />} />
      <Route path="/checkout" element={<Checkout />} />
    </Routes>
  );
}

// Root component
export default function Root() {
  return (
    <RehearsalsProvider>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </RehearsalsProvider>
  );
}

User Identification

function LoginForm() {
  const handleLogin = async (email, password) => {
    const user = await loginUser(email, password);
    
    if (user) {
      // Identify user in Rehearsals
      window.rehearsals?.identify(user.id, {
        email: user.email,
        name: user.name,
        plan: user.subscription,
        createdAt: user.createdAt
      });
    }
  };
  
  return (
    <form onSubmit={handleLogin}>
      {/* Form fields */}
    </form>
  );
}

Next.js Implementation

App Router (app/layout.tsx)

import Script from 'next/script';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <Script
          id="rehearsals-config"
          strategy="beforeInteractive"
          dangerouslySetInnerHTML={{
            __html: `
              window.deepPredictionSettings = {
                apiKey: '${process.env.NEXT_PUBLIC_REHEARSALS_API_KEY}',
                organizationId: '${process.env.NEXT_PUBLIC_REHEARSALS_ORG_ID}',
                cookieDomain: '${process.env.NEXT_PUBLIC_DOMAIN || ''}'
              };
            `,
          }}
        />
        <Script
          src="https://app.runrehearsals.com/recorder.js"
          strategy="afterInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Pages Router (_app.tsx)

import { useEffect } from 'react';
import { useRouter } from 'next/router';
import Script from 'next/script';
import type { AppProps } from 'next/app';

function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter();
  
  useEffect(() => {
    // Track route changes
    const handleRouteChange = (url: string) => {
      window.rehearsals?.trackPageView({ url });
    };
    
    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router.events]);
  
  return (
    <>
      <Script
        id="rehearsals-config"
        strategy="beforeInteractive"
        dangerouslySetInnerHTML={{
          __html: `
            window.deepPredictionSettings = {
              apiKey: '${process.env.NEXT_PUBLIC_REHEARSALS_API_KEY}',
              organizationId: '${process.env.NEXT_PUBLIC_REHEARSALS_ORG_ID}'
            };
          `,
        }}
      />
      <Script
        src="https://app.runrehearsals.com/recorder.js"
        strategy="afterInteractive"
      />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

Vue.js Application

main.js

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

// Configure Rehearsals
window.deepPredictionSettings = {
  apiKey: import.meta.env.VITE_REHEARSALS_API_KEY,
  organizationId: import.meta.env.VITE_REHEARSALS_ORG_ID
};

// Load Rehearsals script
const script = document.createElement('script');
script.src = 'https://app.runrehearsals.com/recorder.js';
script.async = true;
document.head.appendChild(script);

// Create Vue app
const app = createApp(App);

// Track route changes
router.afterEach((to) => {
  window.rehearsals?.trackPageView({
    url: to.fullPath,
    title: to.meta.title || document.title
  });
});

// Rehearsals plugin
app.config.globalProperties.$rehearsals = {
  track: (event, properties) => {
    window.rehearsals?.trackEvent(event, properties);
  },
  identify: (userId, traits) => {
    window.rehearsals?.identify(userId, traits);
  }
};

app.use(router).mount('#app');

Component Usage

<template>
  <button @click="handlePurchase">Buy Now</button>
</template>

<script>
export default {
  methods: {
    handlePurchase() {
      // Track purchase event
      this.$rehearsals.track('purchase_clicked', {
        product: this.product.name,
        price: this.product.price
      });
      
      // Process purchase
      this.processPurchase();
    }
  }
}
</script>

Angular Application

app.module.ts

import { APP_INITIALIZER, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { RehearsalsService } from './services/rehearsals.service';

function initializeRehearsals(): () => Promise<void> {
  return () => {
    return new Promise((resolve) => {
      // Configure
      (window as any).deepPredictionSettings = {
        apiKey: environment.rehearsalsApiKey,
        organizationId: environment.rehearsalsOrgId
      };
      
      // Load script
      const script = document.createElement('script');
      script.src = 'https://app.runrehearsals.com/recorder.js';
      script.async = true;
      script.onload = () => resolve();
      document.head.appendChild(script);
    });
  };
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    RehearsalsService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeRehearsals,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

rehearsals.service.ts

import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class RehearsalsService {
  constructor(private router: Router) {
    // Track route changes
    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe((event: NavigationEnd) => {
        this.trackPageView(event.url);
      });
  }
  
  trackEvent(name: string, properties?: any): void {
    (window as any).rehearsals?.trackEvent(name, properties);
  }
  
  trackPageView(url: string): void {
    (window as any).rehearsals?.trackPageView({ url });
  }
  
  identify(userId: string, traits?: any): void {
    (window as any).rehearsals?.identify(userId, traits);
  }
}

E-commerce Implementation

Product Page

// Track product views
window.rehearsals?.trackEvent('product_viewed', {
  productId: 'SKU123',
  productName: 'Wireless Headphones',
  price: 99.99,
  category: 'Electronics',
  inStock: true
});

// Track add to cart
document.getElementById('add-to-cart').addEventListener('click', () => {
  window.rehearsals?.trackEvent('add_to_cart', {
    productId: 'SKU123',
    quantity: 1,
    price: 99.99
  });
});

Checkout Flow

// Track checkout steps
class CheckoutTracker {
  constructor() {
    this.currentStep = 1;
  }
  
  trackStep(stepName, data) {
    window.rehearsals?.trackEvent('checkout_step', {
      step: this.currentStep,
      stepName: stepName,
      ...data
    });
    this.currentStep++;
  }
  
  trackPurchase(orderData) {
    window.rehearsals?.trackEvent('purchase_completed', {
      orderId: orderData.id,
      total: orderData.total,
      items: orderData.items.length,
      paymentMethod: orderData.paymentMethod,
      shippingMethod: orderData.shippingMethod
    });
  }
}

const tracker = new CheckoutTracker();

// Usage
tracker.trackStep('shipping_info', { 
  country: 'US',
  express: false 
});

tracker.trackStep('payment_info', { 
  method: 'credit_card' 
});

tracker.trackPurchase({
  id: 'ORDER123',
  total: 299.97,
  items: [/* ... */],
  paymentMethod: 'credit_card',
  shippingMethod: 'standard'
});

SaaS Application

Feature Usage Tracking

class FeatureTracker {
  trackFeatureUsage(featureName, metadata = {}) {
    window.rehearsals?.trackEvent('feature_used', {
      feature: featureName,
      timestamp: new Date().toISOString(),
      ...metadata
    });
  }
  
  trackError(error, context = {}) {
    window.rehearsals?.trackEvent('error_occurred', {
      message: error.message,
      stack: error.stack,
      url: window.location.href,
      ...context
    });
  }
  
  trackPerformance(metric, value) {
    window.rehearsals?.trackEvent('performance_metric', {
      metric: metric,
      value: value,
      timestamp: Date.now()
    });
  }
}

// Usage
const tracker = new FeatureTracker();

// Track feature usage
tracker.trackFeatureUsage('export_csv', {
  rowCount: 5000,
  duration: 2.3
});

// Track errors
window.addEventListener('error', (event) => {
  tracker.trackError(event.error, {
    component: 'global'
  });
});

// Track performance
tracker.trackPerformance('api_response_time', 245);

A/B Testing Integration

// Generic A/B test tracking
class ABTestRecorder {
  constructor() {
    this.experiments = new Map();
  }
  
  recordExperiment(experimentId, variant) {
    this.experiments.set(experimentId, variant);
    
    // Send to Rehearsals
    window.rehearsals?.trackEvent('experiment_activated', {
      experimentId: experimentId,
      variant: variant,
      timestamp: Date.now()
    });
    
    // Add to session metadata
    window.rehearsals?.setSessionData({
      experiments: Object.fromEntries(this.experiments)
    });
  }
  
  recordConversion(experimentId, conversionType) {
    const variant = this.experiments.get(experimentId);
    
    window.rehearsals?.trackEvent('experiment_conversion', {
      experimentId: experimentId,
      variant: variant,
      conversionType: conversionType
    });
  }
}

// Usage
const abTest = new ABTestRecorder();

// Record experiment participation
abTest.recordExperiment('checkout_flow_v2', 'variant_b');

// Record conversion
abTest.recordConversion('checkout_flow_v2', 'purchase');
Liam Bolling·CEO & Co‑Founder
Created June 15, 2025·Updated September 12, 2025