Next.js
Next.js chat app components for messaging between users
A Next.js chat app is either an AI chatbot or chat between your users. TalkJS is for the second kind. You get React chat components and the backend that stores and delivers every message. Load the chat only in the browser, through a dynamic import. On Next.js 16 this builds with the default settings and keeps the chat’s 317 kB of JavaScript off the first page load.
'use client';
// app/messages/ChatLoader.tsx
import dynamic from 'next/dynamic';
const Chat = dynamic(() => import('./Chat'), {
ssr: false,
});
export default function ChatLoader() {
return <Chat />;
}

Which Next.js chat component fits chat between your users?
One that comes with a backend. A chat component for an AI chatbot shows a model’s reply as it streams in. Chat between people needs more behind the component: every message stored, delivered to the other person in real time, and still reaching them by email or push when they’re offline.
The TalkJS Chatbox, Inbox, and ConversationList components come with that backend, and every plan includes email and mobile push notifications, SMS (charged separately), and moderation tools. Once you launch, you pay per monthly active user: Basic is $279 a month ($239 billed annually) for 10,000 users.
Add chat to your Next.js app with a dynamic import
Install the TalkJS React components and the JavaScript Data API:
npm install @talkjs/react-components @talkjs/corePut the chat in a Client Component of its own. This is the Chatbox from the Next.js getting started guide, showing a sample conversation from your test mode:
// app/messages/Chat.tsx
'use client';
import { Chatbox } from '@talkjs/react-components';
import '@talkjs/react-components/default.css';
export default function Chat() {
return (
<Chatbox
style={{ width: '400px', height: '600px' }}
appId="<APP_ID>"
userId="sample_user_alice"
conversationId="sample_conversation"
/>
);
}Then load it from a second, small Client Component with next/dynamic and ssr: false. Next.js doesn’t allow ssr: false in a Server Component (the build stops with “ssr: false is not allowed with next/dynamic in Server Components”), so your page imports the loader, not the chat:
// app/messages/ChatLoader.tsx
'use client';
import dynamic from 'next/dynamic';
const Chat = dynamic(() => import('./Chat'), { ssr: false });
export default function ChatLoader() {
return <Chat />;
}// app/messages/page.tsx (a Server Component)
import ChatLoader from './ChatLoader';
export default function MessagesPage() {
return (
<main>
<h1>Messages</h1>
<ChatLoader />
</main>
);
}Where each file runs
- 1. Serverpage.tsxRenders the page’s HTML, with an empty spot for the chat
- 2. Server and browserChatLoader.tsxLoads with the page and asks for the chat with a dynamic import
- 3. Browser, after the pageChat.tsxArrives in its own chunk and connects to TalkJS
Why not render the chat straight from the page?
create-next-app 16.4.4 turns on Cache Components in next.config.ts. With it on, a page that renders the chat directly works in next dev, but next build stops with “did not produce a static shell and Next.js was unable to determine a reason”. Wrapping the chat in <Suspense> fixes the build, but the chat’s JavaScript still loads with the page. The loader above fixes both.
How much JavaScript a Next.js 16 page loads with each way of adding the chat
next build: Next.js 16.4.4 with Cache Components on, React 19.3.0, @talkjs/ react-components 0.3.12, November 2026.Search engines lose nothing either way: even rendered on the server, the chat is an empty container in the page’s HTML.
Next.js chat API: sign user tokens in a route handler
Before you go live, turn on authentication so that only your users can open their chats. Your server signs a token for the signed-in user, and the chat sends it when it connects. In the App Router that’s a Route Handler. This one uses jose to sign the token with the claims listed in the authentication docs:
// app/api/talkjs-token/route.ts
import { SignJWT } from 'jose';
import { getCurrentUserId } from '@/lib/auth'; // your own session lookup
export async function GET() {
const userId = await getCurrentUserId();
if (!userId) {
return Response.json({ error: 'Not signed in' }, { status: 401 });
}
const secret = new TextEncoder().encode(process.env.TALKJS_SECRET_KEY);
const token = await new SignJWT({ tokenType: 'user' })
.setProtectedHeader({ alg: 'HS256' })
.setIssuer(process.env.NEXT_PUBLIC_TALKJS_APP_ID!)
.setSubject(userId)
.setExpirationTime('1d')
.sign(secret);
return Response.json({ token });
}Take the user ID from your session, never from the request, or anyone could ask for anyone’s token. In the chat component, fetch the token and register it before the chat mounts with getTalkSession({ appId, userId }).setToken(token). Then turn on Authentication (identity verification) in the security settings on the Settings page of your dashboard.
We were able to offload all messaging to TalkJS — hugely simplifying our development of an otherwise complex stack.
Next.js chat UI kit you can customize
You style the pre-built chat UIs with properties, CSS, or a custom theme, as the customization guide shows. Need a chat popup? Show a Chatbox when the user clicks a button of your own.
The TalkJS Inbox shows the chat history on the left, selected conversation on the right. It’s designed to act as the messaging center of your app, usually living on its own page.
The TalkJS Chatbox is the right half of the Inbox UI mode. It takes up less space and is designed to be embedded in your app near an order confirmation, a booking, or user profile.
The user’s conversations in one list. Put a Chatbox next to it to open the one they pick, or use the Inbox, which combines the two.
FAQs
Yes. TalkJS runs in the browser, so the chat goes in a Client Component with 'use client' at the top, and your pages load it through a small client loader with next/dynamic and ssr: false, as shown above.
Yes. Import the Chatbox straight into a Pages Router page. Its JavaScript then loads with the page, so if you’d rather load it after, use next/dynamic with ssr: false.
Connect your own AI agent with webhooks and the REST API. A webhook notifies your server when a user sends a message, your agent generates a reply, and the REST API sends it back into the conversation. TalkJS doesn’t include its own AI agent, so you choose the model.
TalkJS is free in development mode with full feature access. You only need a paid plan once you go live with real users. See Pricing for details.
Yes. Paste “Add TalkJS chat to my app: talkjs.com/SKILL.md” into your coding agent. Or follow the Next.js getting started guide to set it up yourself.