Documentation Index
Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt
Use this file to discover all available pages before exploring further.
Deployment
This guide covers everything you need to deploy your Fanfare integration to production, including environment configuration, security considerations, and monitoring.
Pre-Deployment Checklist
Before deploying to production, verify the following:
1. Use Production Credentials
Ensure you are using production API keys, not test keys:
// Production
<FanfareProvider
organizationId={process.env.NEXT_PUBLIC_FANFARE_ORG_ID}
publishableKey={process.env.NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY} // pk_live_...
environment="production"
>
Production keys:
- Start with
pk_live_
- Connect to
https://api.fanfare.io
- Use your production organization data
2. Remove Debug Mode
Disable debug logging in production:
<FanfareProvider
organizationId={process.env.NEXT_PUBLIC_FANFARE_ORG_ID}
publishableKey={process.env.NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY}
debug={false} // Always false in production
logging={{ level: "error" }} // Only log errors
>
3. Verify Environment Variables
Ensure all required environment variables are set in your production environment:
# Required
NEXT_PUBLIC_FANFARE_ORG_ID=org_your_production_id
NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY=pk_live_your_production_key
# Optional
NEXT_PUBLIC_FANFARE_ENVIRONMENT=production
4. Test Production Configuration Locally
Before deploying, test with production credentials locally:
# Create a .env.production.local file (gitignored)
NEXT_PUBLIC_FANFARE_ORG_ID=org_production_123
NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY=pk_live_xyz789
# Run with production config
npm run build && npm run start
Backend Integration
Validating Admission Tokens
When customers are admitted, they receive an admission token. Your backend must validate this token before completing the transaction.
// Your backend API
import { createHmac } from "crypto";
interface AdmissionValidation {
valid: boolean;
experienceId?: string;
consumerId?: string;
admittedAt?: string;
expiresAt?: string;
}
async function validateAdmissionToken(token: string): Promise<AdmissionValidation> {
const response = await fetch("https://api.fanfare.io/v1/admissions/validate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.FANFARE_SECRET_KEY}`,
"X-Organization-Id": process.env.FANFARE_ORG_ID!,
},
body: JSON.stringify({ token }),
});
if (!response.ok) {
return { valid: false };
}
return response.json();
}
Security Note: Never expose your secret API key (sk_live_...) in client-side code. Only use it in your backend.
Webhook Integration
Set up webhooks to receive real-time notifications about experience events:
Common webhook events:
| Event | Description |
|---|
queue.admitted | Consumer was admitted from queue |
draw.completed | Draw finished, winners selected |
auction.ended | Auction ended |
admission.expired | Admission token expired |
Example webhook handler:
// pages/api/webhooks/fanfare.ts (Next.js)
import { NextApiRequest, NextApiResponse } from "next";
import { createHmac } from "crypto";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") {
return res.status(405).end();
}
// Verify webhook signature
const signature = req.headers["x-fanfare-signature"] as string;
const payload = JSON.stringify(req.body);
const expectedSignature = createHmac("sha256", process.env.FANFARE_WEBHOOK_SECRET!).update(payload).digest("hex");
if (signature !== expectedSignature) {
return res.status(401).json({ error: "Invalid signature" });
}
// Handle the event
const event = req.body;
switch (event.type) {
case "queue.admitted":
// Handle queue admission
await handleQueueAdmission(event.data);
break;
case "draw.completed":
// Handle draw completion
await handleDrawCompletion(event.data);
break;
default:
console.log("Unhandled event type:", event.type);
}
res.status(200).json({ received: true });
}
Security Considerations
Content Security Policy (CSP)
Allow connections to Fanfare APIs in your CSP:
// next.config.js
const securityHeaders = [
{
key: "Content-Security-Policy",
value: `
default-src 'self';
connect-src 'self' https://api.fanfare.io https://beacon.fanfare.io;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
`.replace(/\n/g, ""),
},
];
module.exports = {
async headers() {
return [
{
source: "/(.*)",
headers: securityHeaders,
},
];
},
};
CORS Configuration
The Fanfare API handles CORS automatically. Ensure your domain is registered in your Fanfare dashboard.
Rate Limiting
The Fanfare API has rate limits to protect against abuse:
| Endpoint | Limit |
|---|
| Queue entry | 100 requests/minute per IP |
| Draw entry | 100 requests/minute per IP |
| Auction bidding | 60 requests/minute per consumer |
| Status polling | 120 requests/minute per consumer |
The SDK handles rate limit errors gracefully with exponential backoff.
Bundle Size
Verify your bundle size includes only what you need:
# Analyze bundle
npm run build -- --analyze
The SDK supports tree-shaking. If you only use queues, draw/auction code is not included.
Lazy Loading
Load Fanfare components lazily if they are not needed on initial page load:
import { lazy, Suspense } from "react";
const QueueWidget = lazy(() => import("@fanfare/react").then((m) => ({ default: m.QueueWidget })));
function ProductPage() {
return (
<div>
<h1>Product Details</h1>
{/* QueueWidget loads only when rendered */}
<Suspense fallback={<div>Loading queue...</div>}>
<QueueWidget experienceId="exp_123" />
</Suspense>
</div>
);
}
Preconnect to API
Add preconnect hints to reduce connection latency:
<head>
<link rel="preconnect" href="https://api.fanfare.io" />
<link rel="preconnect" href="https://beacon.fanfare.io" />
</head>
Monitoring and Observability
Error Tracking
Integrate with your error tracking service:
import * as Sentry from "@sentry/react";
import { FanfareProvider } from "@fanfare/react";
function App() {
return (
<Sentry.ErrorBoundary fallback={<ErrorFallback />}>
<FanfareProvider
organizationId={process.env.NEXT_PUBLIC_FANFARE_ORG_ID!}
publishableKey={process.env.NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY!}
>
<YourApp />
</FanfareProvider>
</Sentry.ErrorBoundary>
);
}
Analytics Events
Track Fanfare events in your analytics:
import { useFanfare } from "@fanfare/react";
import { useEffect } from "react";
function AnalyticsTracker() {
const fanfare = useFanfare();
useEffect(() => {
const unsubscribeAdmitted = fanfare.on("queue:admitted", (data) => {
// Track in your analytics
analytics.track("Queue Admitted", {
queueId: data.queueId,
});
});
const unsubscribeDrawWon = fanfare.on("draw:won", (data) => {
analytics.track("Draw Won", {
drawId: data.drawId,
});
});
return () => {
unsubscribeAdmitted();
unsubscribeDrawWon();
};
}, [fanfare]);
return null;
}
Health Checks
Monitor Fanfare API availability:
// health-check.ts
async function checkFanfareHealth(): Promise<boolean> {
try {
const response = await fetch("https://api.fanfare.io/health", {
timeout: 5000,
});
return response.ok;
} catch {
return false;
}
}
Vercel
# Set environment variables in Vercel dashboard or CLI
vercel env add NEXT_PUBLIC_FANFARE_ORG_ID
vercel env add NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY
# Deploy
vercel --prod
Netlify
# netlify.toml
[build]
command = "npm run build"
publish = ".next"
[build.environment]
NEXT_PUBLIC_FANFARE_ORG_ID = "org_your_id"
NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY = "pk_live_your_key"
AWS Amplify
# amplify.yml
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- "**/*"
cache:
paths:
- node_modules/**/*
Set environment variables in the Amplify console.
Docker
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
ARG NEXT_PUBLIC_FANFARE_ORG_ID
ARG NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY
ENV NEXT_PUBLIC_FANFARE_ORG_ID=$NEXT_PUBLIC_FANFARE_ORG_ID
ENV NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY=$NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3000
CMD ["npm", "start"]
Post-Deployment Verification
After deploying, verify your integration:
1. Test the Full Flow
- Visit your production site
- Join a queue/draw/auction
- Verify you are admitted (use a test experience if needed)
- Complete a test transaction
- Verify the admission token was validated
2. Check Logging
Monitor your application logs for any Fanfare-related errors:
# Vercel
vercel logs --follow
# Docker
docker logs -f your-container
3. Verify Webhooks
Trigger a test event and verify your webhook endpoint receives it:
- Go to Fanfare Dashboard > Webhooks
- Click “Send Test Event”
- Verify your endpoint returns 200 OK
4. Monitor Metrics
Check your Fanfare dashboard for:
- Request volume
- Error rates
- Average queue times
- Conversion rates
Rollback Plan
Have a rollback plan ready:
- Feature Flag: Use a feature flag to disable Fanfare integration quickly
- Fallback UI: Show a fallback message if Fanfare is unavailable
- Previous Version: Keep the previous deployment available for quick rollback
function ProductPage() {
const fanfareEnabled = useFeatureFlag("fanfare_enabled");
if (!fanfareEnabled) {
return <FallbackProductPage />;
}
return (
<FanfareProvider {...config}>
<ProductWithQueue />
</FanfareProvider>
);
}
Next Steps