React / Next.js Integration
Integrate SilentShield into React and Next.js applications using a custom hook.
1. Create a Hook
Create a reusable hook to load and initialize SilentShield:
hooks/useSilentShield.tstypescript
// hooks/useSilentShield.ts
import { useEffect } from 'react';
export function useSilentShield(apiKey: string) {
useEffect(() => {
const script = document.createElement('script');
script.src = `https://api.silentshield.io/client.js?key=${apiKey}`;
script.defer = true;
script.onload = () => {
(window as any).SilentShield?.init({ apiKey });
};
document.head.appendChild(script);
return () => {
document.head.removeChild(script);
};
}, [apiKey]);
}2. Use in Your Component
Call the hook in any component that contains a form:
ContactPage.tsxtypescript
import { useSilentShield } from '@/hooks/useSilentShield';
export default function ContactPage() {
useSilentShield(process.env.NEXT_PUBLIC_SILENTSHIELD_KEY!);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const nonce = formData.get('ss_nonce') as string;
const res = await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify({
...Object.fromEntries(formData),
ss_nonce: nonce,
}),
});
};
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<textarea name="message" required />
<button type="submit">Send</button>
</form>
);
}3. Next.js Script Component
Alternatively, use Next.js Script component in your layout:
app/layout.tsxtypescript
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src={`https://api.silentshield.io/client.js?key=${process.env.NEXT_PUBLIC_SILENTSHIELD_KEY}`}
strategy="afterInteractive"
onLoad={() => {
(window as any).SilentShield?.init({
apiKey: process.env.NEXT_PUBLIC_SILENTSHIELD_KEY,
});
}}
/>
</body>
</html>
);
}4. Server-Side Verification (API Route)
Verify the nonce in your Next.js API route or Server Action:
app/api/contact/route.tstypescript
// app/api/contact/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(req: NextRequest) {
const body = await req.json();
const nonce = body.ss_nonce;
if (!nonce) {
return NextResponse.json({ error: 'Missing nonce' }, { status: 422 });
}
const verify = await fetch(
'https://api.silentshield.io/api/v1/captcha/verify-nonce',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': process.env.SILENTSHIELD_API_KEY!,
},
body: JSON.stringify({ nonce }),
}
);
const result = await verify.json();
if (result.verdict === 'bot') {
return NextResponse.json({ error: 'Bot detected' }, { status: 403 });
}
// Process the form...
return NextResponse.json({ success: true });
}