Next.js SDK
Integrate Perly churn prevention into your Next.js application using the instrumentation hook and a user resolver.
@perly/nextjsv1.0.05 minutes
Installation
npm install @perly/nextjs @perly/coreUsage
The Next.js SDK uses the instrumentation hook pattern. Start by creating a Perly initialization file and importing it from instrumentation.ts.
1. Initialize Perly
// lib/perly.ts
import { init, PerlyBuilder } from '@perly/nextjs';
init({
apiKey: process.env.PERLY_API_KEY!,
userResolver: (req) => {
const userId = req.headers.get('x-user-id');
if (!userId) return null;
return new PerlyBuilder()
.setId(userId)
.build();
},
});2. Register via Instrumentation
// instrumentation.ts (project root)
export async function register() {
await import('./lib/perly');
}This ensures Perly is initialized once when the Next.js server starts.
User Resolver
The userResolver is an async function that receives the incoming request and returns a Perly user. Return null for unauthenticated requests to skip tracking.
// lib/perly.ts
import { init, PerlyBuilder } from '@perly/nextjs';
import { getServerSession } from 'next-auth';
init({
apiKey: process.env.PERLY_API_KEY!,
userResolver: async (req) => {
const session = await getServerSession();
if (!session?.user) return null;
return new PerlyBuilder()
.setId(session.user.id)
.setMetadata({
plan: session.user.plan,
region: session.user.region,
})
.linkStripeById(session.user.stripeCustomerId)
.linkHubspotById(session.user.hubspotContactId)
.build();
},
});Tracking Events
Use the getPerly() helper inside API routes and server actions to track customer events.
// app/api/onboarding/complete/route.ts
import { getPerly } from '@perly/nextjs';
export async function POST(req: Request) {
const perly = getPerly();
await perly.track('onboarding_completed');
return Response.json({ success: true });
}
// app/api/reports/export/route.ts
export async function POST(req: Request) {
const perly = getPerly();
const body = await req.json();
await perly.track('report_exported', { format: body.format });
return Response.json({ url: reportUrl });
}Expansion Signals
Send expansion signals from server-side code when customers approach usage limits.
import { getPerly } from '@perly/nextjs';
export async function POST(req: Request) {
const perly = getPerly();
await perly.signal('seat_limit_near', {
current: 48,
limit: 50,
});
await perly.signal('token_usage_high', {
current: 950000,
limit: 1000000,
period: 'monthly',
});
return Response.json({ acknowledged: true });
}