Next.js App Router
Capture and replay your first Next.js backend run in 5 minutes.
Three steps: install, add env vars, wrap your route. No CLI, no generators, no config files beyond next.config.ts.
Install and configure env vars
Create an app in FluxRun, then add these server-only values to local development and your deployment environment.
npm install fluxrunFLUX_PROJECT_TOKEN=fbproj_...
FLUX_PUBLIC_KEY=fluxpub_v1_...
FLUX_PRIVATE_KEY=fluxpriv_v1_...Tip: You only need these three values. The SDK already knows the production ingest endpoint, so no URL configuration is required.
Wrap Next config
This snippet should typecheck on Next 15 without casts.
// next.config.ts
import type { NextConfig } from 'next';
import { withFluxNextJsPlugin } from 'fluxrun/build';
const nextConfig: NextConfig = {};
const withFlux = withFluxNextJsPlugin();
export default withFlux(nextConfig);Why: The plugin rewrites host-module imports so Next can bundle them correctly before the route compiles.
Wrap one route handler
Use fluxHost for live SDK clients or database handles. The host method can keep normal typed parameters.
// app/api/orders/route.ts
import { withFluxNextJs } from 'fluxrun/adapters/next';
import { fluxHost } from 'fluxrun';
import { prisma } from '@/lib/prisma';
export const runtime = 'nodejs';
type OrderInput = { amount: number; currency: string };
const db = fluxHost('db', {
createOrder: async (input: OrderInput) => prisma.order.create({ data: input }),
});
export const POST = withFluxNextJs(
'orders.create',
async (flux) => {
const body = flux.request.body as OrderInput;
const order = await db.createOrder(body);
return { status: 201, body: { id: order.id } };
},
{ host: { db } },
);Required: Always export runtime = "nodejs" in traced routes. FluxRun uses QuickJS, which needs the Node.js runtime. Without this, the route will fail at runtime.
Why fluxHost: Prisma and other live clients cannot be serialized into the QuickJS sandbox. fluxHost keeps them on the host side while recording every call for replay.
Add the replay agent route
Save this deployed URL in the app dashboard, for example https://your-app.com/api/flux-agent.
// app/api/flux-agent/route.ts
import { fluxAgent } from 'fluxrun';
export const runtime = 'nodejs';
const corsHeaders = {
'Access-Control-Allow-Origin': 'https://app.fluxrun.dev',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
};
export async function OPTIONS() {
return new Response(null, { headers: corsHeaders });
}
export async function POST(req: Request) {
const result = await fluxAgent(await req.json(), {
authorization: req.headers.get('authorization'),
});
return Response.json(result, { headers: corsHeaders });
}Why: The dashboard never holds your private key. When you click "replay," the dashboard asks your agent to decrypt and re-run the trace using your key.
Optional local ingest stub
Normal apps should not set FLUX_INGEST_URL in production. For local smoke tests only.
// app/api/flux-ingest/v1/executions/route.ts
type LocalFluxBatch = {
executionId?: string;
summary?: { executionId?: string };
events?: unknown[];
};
export const runtime = 'nodejs';
export async function POST(req: Request) {
const batch = (await req.json()) as LocalFluxBatch;
console.log('[fluxrun local ingest]', {
executionId: batch.executionId ?? batch.summary?.executionId,
events: batch.events?.length ?? 0,
});
return Response.json({ ok: true });
}Tip: Skip this step if you are deploying straight to production. The SDK sends traces to FluxRun automatically.
Verify it works
Build the app, trigger the route, then open the dashboard. A successful setup shows a new execution with request, host calls, fetches, console, errors, and replay actions.
npm install fluxrun
npm run build
curl -X POST http://localhost:3000/api/orders \
-H 'content-type: application/json' \
-d '{"amount":1250,"currency":"usd"}'Common Next.js pitfalls
Use Node.js runtime
Traced App Router handlers and the agent route should export runtime = "nodejs".
Do not set FLUX_INGEST_URL in production
The SDK already knows the production ingest endpoint. Set it only for local or private ingest overrides.
Local ingest path is appended
If FLUX_INGEST_URL=/api/flux-ingest, FluxRun posts to /api/flux-ingest/v1/executions.
Keep private keys server-side
FLUX_PRIVATE_KEY belongs only in server runtimes that run traced routes and the agent route.
Wrap host boundaries
Put Prisma, Redis, queues, payment clients, and other live SDK clients behind fluxHost.
Verify the agent URL
Save the deployed /api/flux-agent URL in the dashboard before decrypt or replay.