Framework Quickstarts
Next.js quickstart
Integrate npayload with Next.js App Router using server actions and React hooks
Add real-time messaging to a Next.js App Router application using @npayload/node for server-side operations and @npayload/react for client-side hooks.
Prerequisites
- Next.js 14+ with App Router
- An npayload account with machine credentials (get them here)
Install the SDKs
npm install @npayload/node @npayload/react @npayload/jsAdd credentials to .env.local:
NPAYLOAD_CLIENT_ID=oac_your_client_id
NPAYLOAD_HMAC_SECRET=your_hmac_secret
NEXT_PUBLIC_NPAYLOAD_KEY=pk_live_your_publishable_keyCreate the server client
// lib/npayload.ts
import { NPayloadAuth, NPayloadClient } from '@npayload/node';
const auth = new NPayloadAuth({
clientId: process.env.NPAYLOAD_CLIENT_ID!,
hmacSecret: process.env.NPAYLOAD_HMAC_SECRET!,
});
export const npayload = new NPayloadClient({ auth });Add the React provider
// app/providers.tsx
'use client';
import { NPayloadProvider } from '@npayload/react';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<NPayloadProvider
config={{
publishableKey: process.env.NEXT_PUBLIC_NPAYLOAD_KEY!,
}}
>
{children}
</NPayloadProvider>
);
}// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Create a server action for publishing
// app/actions.ts
'use server';
import { npayload } from '@/lib/npayload';
export async function publishMessage(channel: string, payload: unknown) {
const message = await npayload.messages.publish({ channel, payload });
return { messageId: message.gid };
}Build the page with real-time updates
// app/page.tsx
'use client';
import { useMessages, usePublish } from '@npayload/react';
import { publishMessage } from './actions';
export default function Home() {
const { messages, isLoading } = useMessages('notifications');
const { publish, isPublishing } = usePublish('notifications');
const handlePublish = async () => {
await publishMessage('notifications', {
event: 'greeting',
message: 'Hello from Next.js!',
timestamp: new Date().toISOString(),
});
};
return (
<main>
<h1>npayload + Next.js</h1>
<button onClick={handlePublish} disabled={isPublishing}>
{isPublishing ? 'Publishing...' : 'Publish message'}
</button>
<h2>Messages</h2>
{isLoading ? (
<p>Loading...</p>
) : (
<ul>
{messages.map((msg) => (
<li key={msg.gid}>
{JSON.stringify(msg.payload)}
</li>
))}
</ul>
)}
</main>
);
}Add a webhook route
// app/api/webhooks/npayload/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { npayload } from '@/lib/npayload';
export async function POST(req: NextRequest) {
const body = await req.json();
const signature = req.headers.get('x-npayload-signature')!;
const isValid = npayload.webhooks.verify(
body,
signature,
process.env.WEBHOOK_SECRET!
);
if (!isValid) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
}
// Process the webhook
console.log('Webhook received:', body.payload);
return NextResponse.json({ received: true });
}Next steps
- React SDK for all available hooks
- Node.js SDK for server-side operations
- Webhooks guide for production webhook patterns
Was this page helpful?