Build chat applications with PubNub Chat SDK
Agent Success
Agent success rate when using this tile
95%
Improvement
Agent success rate improvement when using this tile compared to baseline
1.83x
Baseline
Agent success rate without this tile
52%
npm install @pubnub/chat
# or
yarn add @pubnub/chatimport { Chat } from '@pubnub/chat';
const chat = await Chat.init({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'user-123'
});const chat = await Chat.init({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'unique-user-id', // REQUIRED - persistent per user
// Optional configurations
authKey: 'pam-auth-token', // For Access Manager (NOT 'token')
cipherKey: 'encryption-key', // For message encryption
// Typing indicator settings
typingTimeout: 5000, // ms before typing indicator expires
storeUserActivityTimestamps: true, // Track user activity
// Rate limiting
rateLimitFactor: 2, // Multiplier for rate limits
rateLimitPerChannel: 20 // Messages per minute per channel
});// Use authKey for client configuration
const chat = await Chat.init({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'user-123',
authKey: 'auth-token-from-server' // CORRECT
});// DO NOT use 'token' parameter
const chat = await Chat.init({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'user-123',
token: 'auth-token-from-server' // WRONG - will not work
});// Current user is available after init
const currentUser = chat.currentUser;
// Update current user's profile
await currentUser.update({
name: 'Alice Smith',
profileUrl: 'https://example.com/avatar.png',
custom: {
role: 'member',
preferences: { theme: 'dark' }
}
});// Get existing user
let user = await chat.getUser('other-user-id');
// Create if doesn't exist
if (!user) {
user = await chat.createUser('other-user-id', {
name: 'Bob Jones',
profileUrl: 'https://example.com/bob.png'
});
}async function getOrCreateUser(chat, userId, userData) {
let user = await chat.getUser(userId);
if (!user) {
user = await chat.createUser(userId, userData);
}
return user;
}
// Usage
const interlocutor = await getOrCreateUser(chat, 'bob-123', {
name: 'Bob',
profileUrl: 'https://example.com/bob.png'
});import { useState, useEffect } from 'react';
import { Chat } from '@pubnub/chat';
function ChatApp({ userId }) {
const [chat, setChat] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let mounted = true;
async function initChat() {
try {
const chatInstance = await Chat.init({
publishKey: process.env.REACT_APP_PUBNUB_PUB_KEY,
subscribeKey: process.env.REACT_APP_PUBNUB_SUB_KEY,
userId: userId
});
if (mounted) {
setChat(chatInstance);
setLoading(false);
}
} catch (err) {
if (mounted) {
setError(err);
setLoading(false);
}
}
}
initChat();
return () => {
mounted = false;
// Cleanup will be handled by chat.disconnect()
};
}, [userId]);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <ChatInterface chat={chat} />;
}import { createContext, useContext, useState, useEffect } from 'react';
import { Chat } from '@pubnub/chat';
const ChatContext = createContext(null);
export function ChatProvider({ userId, children }) {
const [chat, setChat] = useState(null);
useEffect(() => {
let chatInstance = null;
Chat.init({
publishKey: process.env.REACT_APP_PUBNUB_PUB_KEY,
subscribeKey: process.env.REACT_APP_PUBNUB_SUB_KEY,
userId
}).then(instance => {
chatInstance = instance;
setChat(instance);
});
return () => {
if (chatInstance) {
chatInstance.disconnect();
}
};
}, [userId]);
return (
<ChatContext.Provider value={chat}>
{children}
</ChatContext.Provider>
);
}
export function useChat() {
return useContext(ChatContext);
}REACT_APP_PUBNUB_PUB_KEY=pub-c-...
REACT_APP_PUBNUB_SUB_KEY=sub-c-...VITE_PUBNUB_PUB_KEY=pub-c-...
VITE_PUBNUB_SUB_KEY=sub-c-...const chat = await Chat.init({
publishKey: import.meta.env.VITE_PUBNUB_PUB_KEY,
subscribeKey: import.meta.env.VITE_PUBNUB_SUB_KEY,
userId: currentUserId
});// Disconnect and cleanup
async function logout(chat) {
await chat.disconnect();
// Clear any cached channels
Object.keys(activeChannels).forEach(key => delete activeChannels[key]);
}
// React cleanup
useEffect(() => {
return () => {
if (chat) {
chat.disconnect();
}
};
}, [chat]);try {
const chat = await Chat.init({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'user-123'
});
} catch (error) {
if (error.status?.category === 'PNAccessDeniedCategory') {
console.error('Access denied - check authKey');
// Refresh auth token
} else if (error.message?.includes('userId')) {
console.error('Invalid userId');
} else {
console.error('Chat initialization failed:', error);
}
}