React / Next.js-integration

Integrer SilentShield i React- og Next.js-applikationer ved hjælp af en tilpasset hook.

1. Opret en Hook

Opret en genanvendelig hook til at indlæse og initialisere 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. Brug i din komponent

Kald hooken i enhver komponent, der indeholder en formular:

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-komponent

Alternativt kan du bruge Next.js Script-komponenten i dit 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. Serversideverificering (API Route)

Verificer nonce i din Next.js API-rute eller 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 });
}