TrueSift Next.js SDK
For React / Next.js App Router only. For Svelte 5 / SvelteKit use the Svelte SDK documentation.
The official @truesift/next package provides a client verification widget, local Next.js App Router handlers and server-side business proof verification. Current version: 0.4.0 (0.4.0 release).
Installation
pnpm add @truesift/nextVerification architecture
- Browser:
TrueSiftCheckcalls only local challenge/verify API routes and receives an opaque, short-livedverificationToken. - Next.js server: the local routes communicate with the TrueSift API, keeping credentials and upstream calls off the browser.
- Protected business route: independently fixes the expected action, path and origin, then consumes the one-time proof before the operation.
Next.js App Router integration
Server-only environment configuration
TRUESIFT_API_BASE_URL=https://api.truesift.de
TRUESIFT_SITE_KEY=your_site_key
TRUESIFT_SECRET_KEY=your_secret_key
TRUESIFT_DEFAULT_ACTION=website_check
TRUESIFT_FAIL_OPEN=false
TRUESIFT_TIMEOUT_MS=2500TRUESIFT_API_BASE_URL must be the service origin only, without /api/v1 or endpoint suffixes. Never use NEXT_PUBLIC_ for credentials.
Local browser-facing API handlers
src/app/api/truesift/challenge/route.ts
import { createTrueSiftChallengeHandler } from "@truesift/next/server";
export const dynamic = "force-dynamic";
export const runtime = "nodejs";
export const POST = createTrueSiftChallengeHandler({
apiBaseUrl: process.env.TRUESIFT_API_BASE_URL,
siteKey: process.env.TRUESIFT_SITE_KEY,
secretKey: process.env.TRUESIFT_SECRET_KEY,
defaultAction: process.env.TRUESIFT_DEFAULT_ACTION,
failOpen: process.env.TRUESIFT_FAIL_OPEN === "true",
timeoutMs: Number(process.env.TRUESIFT_TIMEOUT_MS ?? 2500)
});src/app/api/truesift/verify/route.ts
import { createTrueSiftVerifyHandler } from "@truesift/next/server";
export const dynamic = "force-dynamic";
export const runtime = "nodejs";
export const POST = createTrueSiftVerifyHandler({
apiBaseUrl: process.env.TRUESIFT_API_BASE_URL,
siteKey: process.env.TRUESIFT_SITE_KEY,
secretKey: process.env.TRUESIFT_SECRET_KEY,
defaultAction: process.env.TRUESIFT_DEFAULT_ACTION,
failOpen: process.env.TRUESIFT_FAIL_OPEN === "true",
timeoutMs: Number(process.env.TRUESIFT_TIMEOUT_MS ?? 2500)
});The browser calls /api/truesift/challenge and /api/truesift/verify. These local routes forward to the upstream challenge/verify endpoints; never expose the proof-verification endpoint as a public browser proxy.
Client component
"use client";
import { useState } from "react";
import { TrueSiftCheck } from "@truesift/next/client";
export function SecurityCheck() {
const [verificationToken, setVerificationToken] = useState<string | null>(null);
return (
<TrueSiftCheck
action="contact_form"
path="/contact"
challengeUrl="/api/truesift/challenge"
verifyUrl="/api/truesift/verify"
onVerified={(result) => setVerificationToken(result.verificationToken ?? null)}
onError={() => setVerificationToken(null)}
/>
);
}Send verificationToken with the protected form submission. The action and path here are illustrative; replace them with the real protected action and route. Do not trust the UI state as authorization.
Protected business route
import { verifyTrueSiftProof } from "@truesift/next/server";
export async function POST(request: Request): Promise<Response> {
const body: unknown = await request.json();
const verificationToken =
typeof body === "object" && body !== null &&
"verificationToken" in body &&
typeof body.verificationToken === "string"
? body.verificationToken
: "";
const proof = await verifyTrueSiftProof({
verificationToken,
expectedAction: "contact_form",
expectedPath: "/contact",
expectedOrigin: "https://example.com"
});
if (!proof.allowed) {
return Response.json(
{ error: "TRUESIFT_PROOF_REJECTED", reason: proof.reason },
{ status: proof.reason === "unavailable" ? 503 : 403 }
);
}
// Execute the protected operation only after the server-side decision.
return Response.json({ success: true });
}The expected context must be defined by the business route, never copied from the browser. Replace example values with the actual action, route, and origin. On service unavailability, a trusted server-side fail-open policy may return allowed: true with ok: false; handle that explicitly according to your risk policy.
Behavioral Signals v2 (0.4.0)
The optional browser collector counts aggregate pointer movement/presses, scroll, touch, keyboard, focus/blur, visibility, challenge interaction and observation timing during a short cancellable observation window (2,500 ms). Signals are reset for each check and listeners are released on cancellation, retry and unmount. No raw keys, pointer coordinates, form contents, DOM identities, fingerprints or persistent visitor IDs are captured. Missing or insufficient telemetry does not alone prove bot activity. Existing integrations without v2 telemetry remain compatible.
Security and decision handling
Do not accept a browser-reported allowed, decision, score, failOpen, action, path or origin as authorization. Only the opaque verificationToken is accepted as client proof. A validated allow can authorize processing; review and block, missing, expired, invalid, replayed or mismatched proofs remain rejected. Unavailable results are distinct from verified proof; fail-open is a server-controlled policy and should remain disabled for high-risk operations.
Errors and availability
Invalid credentials (401), forbidden/inactive sites (403) and invalid server configuration raise server errors; they are not treated as service unavailability. Network issues, timeouts and retryable upstream failures return an explicit unavailable outcome. Never treat failOpen: true as successful proof consumption (ok remains false).
Presentation and localization
The component supports checkbox, banner, inline, badge; sizes normal, compact, flexible; themes auto, light, dark; locales auto, en, de, bg. Built-in animation has an SVG fallback. The lottie property can configure visual behavior.
Release highlights
0.4.0 (2026-10-12) added optional aggregate Behavioral Signals v2, cancellable observation, forwarding through local verification handlers, and expanded cleanup/testing coverage. 0.3.0 (2026-08-16) introduced aggregate Behavioral Signals v1. 0.2.0 (2026-07-31) introduced server-only verifyTrueSiftProof and deterministic proof handling.
More information
See the SDK overview, interactive SDK page, npm package, and official TrueSift website.