Back to IntegrationsREGISTER YOUR WALLETSource → Source → Source →
Full-Stack Framework
Herald + Next.js
Use Next.js App Router to build a full-stack notification dashboard. Server-side API routes keep your Herald API key secure, while React client components provide an interactive UI for sending notifications, checking delivery status, and managing webhooks.
Ready to ship?
Start sending zero-PII notifications in minutes.
ZK-SECURE SOLANA NATIVE
Initialize SDK
Create a server-side Herald client — never imported in client components.
Next.js / Initialize SDK
1
2
3
4
5
import { Herald } from '@herald-protocol/sdk';
export const herald = new Herald({ apiKey: process.env.HERALD_API_KEY!,});Send Notification (API Route)
POST /api/notify route handler for sending a single notification.
Next.js / Send Notification (API Route)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { NextRequest, NextResponse } from 'next/server';import { herald } from '../../../lib/herald';
export async function POST(req: NextRequest) { const body = await req.json(); const { wallet, subject, body: messageBody, category, idempotencyKey } = body;
if (!wallet || !subject) { return NextResponse.json({ error: 'wallet and subject are required' }, { status: 400 }); }
const result = await herald.notify({ wallet, subject, body: messageBody, category: category ?? 'defi', receipt: true, idempotencyKey, });
return NextResponse.json(result, { status: 202 });}Webhook Handler
Verify HMAC-SHA256 signatures and handle delivery events.
Next.js / Webhook Handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { NextRequest, NextResponse } from 'next/server';import { Herald } from '@herald-protocol/sdk';
const WEBHOOK_SECRET = process.env.HERALD_WEBHOOK_SECRET!;
export async function POST(req: NextRequest) { const signature = req.headers.get('x-herald-signature'); const payload = await req.json(); const rawBody = JSON.stringify(payload);
if (!signature || !WEBHOOK_SECRET) { return NextResponse.json({ error: 'Missing signature or secret' }, { status: 401 }); }
const isValid = await Herald.verifyWebhookSignature(rawBody, signature, WEBHOOK_SECRET);
if (!isValid) { return NextResponse.json({ error: 'Invalid signature' }, { status: 401 }); }
switch (payload.event) { case 'delivery.confirmed': console.log(`✅ ${payload.notificationId} delivered`); break; case 'delivery.failed': console.error(`❌ ${payload.notificationId} failed: ${payload.error}`); break; }
return NextResponse.json({ received: true });}Send from Client Component
React client component calling the API route.
Next.js / Send from Client Component
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'use client';
export function SendNotification() { async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); const data = new FormData(e.currentTarget); const res = await fetch('/api/notify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ wallet: data.get('wallet'), subject: data.get('subject'), body: data.get('body'), }), }); const result = await res.json(); console.log('Notification sent:', result.notificationId); }
return ( <form onSubmit={handleSubmit}> <input name="wallet" placeholder="Wallet address" required /> <input name="subject" placeholder="Subject" required /> <textarea name="body" placeholder="Message body" /> <button type="submit">Send Notification</button> </form> );}Common Patterns
Server-side API routes with route handlers
Client dashboard with React components
Webhook endpoint for delivery callbacks
Delivery status polling
Start building with Herald
Clone the examples repo, copy the code that fits your stack, and deploy.