Integration
Next.js
Full Next.js integration — client components, server-side verification, and middleware protection.
Install
npm install @janus/nextjs @janus/sdkClient-side (App Router)
@janus/nextjs re-exports everything from @janus/react, so you get the same JanusProvider, useJanus, and components.
// app/providers.tsx
"use client";
import { JanusProvider } from '@janus/nextjs';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<JanusProvider config={{
siteKey: process.env.NEXT_PUBLIC_JANUS_SITE_KEY!,
apiUrl: process.env.NEXT_PUBLIC_JANUS_API_URL!,
mode: "invisible",
}}>
{children}
</JanusProvider>
);
}// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Then use useJanus() in any client component — see the React docs.
Server-side verification
Route Handler
// app/api/submit/route.ts
import { verifyJanusToken } from '@janus/nextjs/server';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const body = await request.json();
const result = await verifyJanusToken(body['janus-token'], {
secretKey: process.env.JANUS_SECRET_KEY!,
apiUrl: process.env.JANUS_API_URL!,
});
if (!result.success || result.action === 'block') {
return NextResponse.json({ error: 'Bot detected' }, { status: 403 });
}
// Process the form submission...
return NextResponse.json({ ok: true });
}Server Action
"use server";
import { verifyJanusToken } from '@janus/nextjs/server';
export async function submitForm(formData: FormData) {
const token = formData.get('janus-token') as string;
const result = await verifyJanusToken(token, {
secretKey: process.env.JANUS_SECRET_KEY!,
apiUrl: process.env.JANUS_API_URL!,
});
if (!result.success || result.action === 'block') {
throw new Error('Bot detected');
}
// Process form...
}Middleware protection
Auto-verify POST requests to protected routes:
// middleware.ts
import { withJanusProtection } from '@janus/nextjs/server';
export default withJanusProtection({
secretKey: process.env.JANUS_SECRET_KEY!,
apiUrl: process.env.JANUS_API_URL!,
protectedPaths: ['/api/submit', '/api/contact', '/api/signup'],
rejectActions: ['block'], // also add 'challenge' to be stricter
});
export const config = {
matcher: '/api/:path*',
};CDN script loading
If you prefer loading the SDK from your Janus CDN instead of bundling:
import { JanusScript } from '@janus/nextjs';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<JanusScript src="https://your-janus.com/sdk/v1/janus.js" />
</body>
</html>
);
}Environment variables
# .env.local
NEXT_PUBLIC_JANUS_SITE_KEY=jns_site_live_xxxxxxxxxxxx
NEXT_PUBLIC_JANUS_API_URL=https://your-janus.com
JANUS_SECRET_KEY=jns_secret_live_xxxxxxxxxxxx
JANUS_API_URL=https://your-janus.com