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');