uplift-ab-testing
v1.1.0
Published
A complete A/B testing platform for Next.js applications with multi-armed bandit algorithms, AI-powered variant generation, and comprehensive analytics dashboard
Maintainers
Readme
Uplift
A self-contained A/B testing platform for Next.js applications with multi-armed bandit algorithms, AI-powered variant generation, server-side rendering support, and a comprehensive analytics dashboard.
Features
- Multi-Armed Bandit Algorithms: Thompson Sampling, UCB1, Epsilon-Greedy
- AI-Powered Variants: Generate test variants automatically using OpenRouter
- Admin Dashboard: Full-featured dashboard for managing experiments and viewing analytics
- Visual Editor: Edit variant content directly on your live pages
- Server-Side Rendering: No flash of content (FOUC) - variants are determined server-side
- Engagement Tracking: Automatic scroll depth, time on page, click tracking
- Conversion Tracking: Track conversions with attribution
- Statistical Analysis: Z-tests, confidence intervals, significance testing
- Bot Detection: Excludes bots and crawlers from tracking
- Session Management: Track user sessions with UTM attribution
- Self-Contained: Uses its own PostgreSQL schema (
uplift)
Installation
npm install uplift-ab-testing
# or
bun add uplift-ab-testing
# or
pnpm add uplift-ab-testingQuick Start
1. Set Up Environment Variables
# .env
# Database (required) - use any of these
UPLIFT_DATABASE_URL=postgres://user:password@localhost:5432/myapp
# or DATABASE_URL or POSTGRES_URL
# Admin dashboard password (required for dashboard access)
UPLIFT_ADMIN_PASSWORD=your-secure-password
# AI variant generation (optional - for generating variants with AI)
OPEN_ROUTER_API_KEY=your-openrouter-api-key
# Organization ID (optional - for multi-tenant setups)
UPLIFT_ORGANIZATION_ID=00000000-0000-0000-0000-000000000001Note: Uplift automatically runs database migrations when needed. The schema is created automatically on first use.
2. Copy the Dashboard to Your App
Uplift includes a complete admin dashboard. Copy it to your Next.js app:
# From your project root
cp -r node_modules/uplift-ab-testing/src/dashboard app/uplift/dashboard
cp -r node_modules/uplift-ab-testing/src/api app/uplift/api
cp -r node_modules/uplift-ab-testing/src/login app/uplift/login
cp node_modules/uplift-ab-testing/src/layout.tsx app/uplift/layout.tsx
cp node_modules/uplift-ab-testing/src/page.tsx app/uplift/page.tsxThen visit /uplift in your app to access the dashboard.
3. Set Up the Provider
Wrap your pages with the Uplift provider:
// app/layout.tsx
import { cookies, headers } from 'next/headers'
import { getVariantForPath, flattenVariantContent } from 'uplift-ab-testing/server'
import { UpliftProvider } from 'uplift-ab-testing/client'
import { trackPageView, trackEngagement, trackConversion, storeAssignment } from 'uplift-ab-testing/server'
export default async function RootLayout({ children }) {
const headersList = await headers()
const url = headersList.get('x-url') || '/'
const assignment = await getVariantForPath(url)
return (
<html>
<body>
<UpliftProvider
variant={assignment ? {
experimentId: assignment.experimentId,
variantId: assignment.variantId,
variantName: assignment.variantName,
isControl: assignment.isControl,
content: flattenVariantContent(assignment.content),
} : null}
url={url}
isNewAssignment={assignment?.isNewAssignment}
storeAssignment={storeAssignment}
trackPageView={trackPageView}
trackEngagement={trackEngagement}
trackConversionAction={trackConversion}
>
{children}
</UpliftProvider>
</body>
</html>
)
}4. Add Slots for A/B Content
Use UpliftSlot to mark content that should be replaced by variants:
import { UpliftSlot } from 'uplift-ab-testing/client'
export function HeroSection() {
return (
<section>
<h1>
<UpliftSlot id="hero-headline">
Welcome to Our Product
</UpliftSlot>
</h1>
<p>
<UpliftSlot id="hero-description">
The best solution for your needs.
</UpliftSlot>
</p>
<button data-uplift-cta="hero-cta">
<UpliftSlot id="hero-cta-text">Get Started</UpliftSlot>
</button>
</section>
)
}5. Track Conversions
Use data-uplift-conversion attribute for conversion tracking:
<button data-uplift-conversion="signup">
Sign Up Now
</button>Or programmatically:
import { useUplift } from 'uplift-ab-testing/client'
function CheckoutButton() {
const { trackConversion } = useUplift()
const handleClick = () => {
trackConversion()
// ... checkout logic
}
return <button onClick={handleClick}>Complete Purchase</button>
}Admin Dashboard
The dashboard provides a complete UI for managing experiments:
- Experiments List: View all experiments with status, metrics, and quick actions
- Create Experiment: Set up new experiments with target URLs and allocation strategies
- Visual Editor: Edit variant content directly on your live pages
- AI Variant Generation: Generate test variants automatically using AI
- Analytics: View conversion rates, engagement scores, and statistical significance
- Visitors: Browse visitor profiles, sessions, and conversion history
Access the dashboard at /uplift after copying the dashboard files to your app.
AI Variant Generation
Uplift can automatically generate A/B test variants using AI. This requires an OpenRouter API key.
Setup
- Get an API key from OpenRouter
- Add it to your environment:
OPEN_ROUTER_API_KEY=your-key
Using the Dashboard
- Create an experiment and add a control variant
- Navigate to the AI tab for your experiment
- Optionally provide context about your target audience, product, or brand tone
- Click "Generate Variants" to create AI-powered alternatives
Programmatic Usage
import { aiService } from 'uplift-ab-testing/server'
const result = await aiService.generateVariants(organizationId, {
experimentId: 'exp-id',
controlContent: {
'hero-headline': { type: 'text', content: 'Welcome to Our Product' },
'hero-cta': { type: 'text', content: 'Get Started' },
},
variantCount: 3,
targetAudience: 'Small business owners',
productDescription: 'Project management software',
brandTone: 'professional',
})
// Save the generated variants
await aiService.saveGeneratedVariants(
organizationId,
'exp-id',
result.variants,
'Generated via API'
)Configuration
Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| UPLIFT_DATABASE_URL | PostgreSQL connection string | Yes |
| DATABASE_URL | Fallback connection string | No |
| POSTGRES_URL | Fallback connection string | No |
| UPLIFT_ADMIN_PASSWORD | Password for dashboard login | Yes (for dashboard) |
| OPEN_ROUTER_API_KEY | OpenRouter API key for AI variants | No |
| UPLIFT_ORGANIZATION_ID | Organization ID for multi-tenant | No |
Allocation Strategies
| Strategy | Description |
|----------|-------------|
| EQUAL | Equal traffic distribution |
| THOMPSON | Thompson Sampling (recommended) |
| UCB1 | Upper Confidence Bound |
| EPSILON_GREEDY | Epsilon-greedy exploration |
API Reference
Server Exports (uplift-ab-testing/server)
import {
// Server functions
getVariantForPath,
getVariantById,
flattenVariantContent,
// Database
getDatabase,
ensureSchemaReady,
runMigration,
repository,
// Services
aiService,
analyticsService,
experimentService,
assignmentService,
trackingService,
// Algorithms
thompsonSelect,
ucb1Select,
calculateSignificance,
calculateEngagementScore,
// Auth
verifyAuth,
DEFAULT_ORGANIZATION_ID,
// Server Actions
trackPageView,
trackEngagement,
trackConversion,
storeAssignment,
createExperimentAction,
updateExperimentAction,
// ... and more
} from 'uplift-ab-testing/server'Client Exports (uplift-ab-testing/client)
import {
// Components
UpliftProvider,
UpliftSlot,
UpliftText,
OverlayEditorProvider,
// Hooks
useUplift,
useSlotContent,
useActiveVariant,
useUpliftTracker,
// Utilities
getVisitorId,
generateSessionId,
createEventSender,
} from 'uplift-ab-testing/client'Data Attributes
| Attribute | Description |
|-----------|-------------|
| data-uplift-editable="id" | Marks element for visual editor |
| data-uplift-cta="id" | Track CTA clicks |
| data-uplift-secondary="id" | Track secondary clicks |
| data-uplift-conversion="id" | Track conversions |
Events Tracked
| Event | Trigger |
|-------|---------|
| PAGE_VIEW | Page load |
| SCROLL_25, SCROLL_50, SCROLL_75, SCROLL_100 | Scroll depth |
| TIME_10S, TIME_30S, TIME_60S, TIME_120S | Time on page |
| CLICK_CTA | CTA click |
| CLICK_SECONDARY | Secondary click |
| CONVERSION | Conversion event |
Database Schema
Uplift creates its own schema (uplift) with these tables:
experiments- Experiment configurationvariants- Variant definitions with contentvisitors- Visitor profilesassignments- Visitor to variant assignmentsevents- Tracking eventsmetrics- Aggregated metrics per variantsessions- User session tracking
TypeScript
Full TypeScript support:
import type {
UpliftExperiment,
UpliftVariant,
UpliftMetrics,
UpliftAssignment,
UpliftEvent,
UpliftSession,
UpliftVisitor,
UpliftAllocationStrategy,
UpliftExperimentStatus,
UpliftEventType,
VariantContent,
GenerateVariantsInput,
} from 'uplift-ab-testing'License
MIT
