Building Context-Aware Chat
Overview
Context-aware chat is the core feature of ChatSDK - it allows the AI to understand what page the user is on, what data they're viewing, and what actions are available. This creates smarter, more relevant responses.
How Context-Aware Chat Works
User is viewing: Product Detail Page
↓ (Component calls useChatContext hook)
↓ (Context about page is sent to chat)
↓ (Backend retrieves relevant docs for this product)
↓ (AI generates response considering current context)
↓ (User gets response tailored to current page)The useChatContext Hook
The useChatContext hook allows any component to provide context about the current page or session.
Basic Usage
import { useChatContext } from '@cyborg-sdk/react';
function ProductPage({ productId }) {
const product = useProduct(productId);
// Send context about this page
useChatContext({
pageData: {
currentPage: '/products/' + productId,
description: `Product page for ${product.name}`,
pageTitle: product.name,
},
});
return (
<div>
<h1>{product.name}</h1>
{/* Product details */}
</div>
);
}Page Context (pageData)
Information about the current page the user is viewing:
useChatContext({
pageData: {
// Required: Where is the user?
currentPage: '/products/123',
// Optional: What is this page about?
description: 'Product detail page showing laptop model X1',
// Optional: What elements are on this page?
widgets: ['product-info', 'specifications', 'reviews', 'similar-products'],
// Optional: Any custom data
productId: '123',
productName: 'Laptop Model X1',
category: 'Electronics',
},
});Session Context (sessionData)
Information about the user and their session:
useChatContext({
sessionData: {
userId: 'user_123',
userRole: 'premium',
subscriptionTier: 'pro',
language: 'en',
timezone: 'America/New_York',
previousPages: ['/home', '/products'],
recentActivity: ['viewed-product-x1', 'added-to-cart'],
},
});Practical Examples
Example 1: Product Page
import { useChatContext, useChat } from '@cyborg-sdk/react';
function ProductDetailPage({ productId }) {
const { messages, sendMessage } = useChat();
const product = fetchProduct(productId);
// Share context
useChatContext({
pageData: {
currentPage: '/products/' + productId,
description: `Viewing ${product.name}`,
productId,
productName: product.name,
price: product.price,
category: product.category,
inStock: product.inStock,
widgets: ['product-image', 'specifications', 'reviews', 'add-to-cart'],
},
sessionData: {
userId: currentUser.id,
previouslyViewed: [product.categoryId],
},
});
return (
<div>
<h1>{product.name}</h1>
<p>Price: ${product.price}</p>
{/* Chat would now respond like: */}
{/* "Based on the laptop you're viewing, you might also like..." */}
<ChatWidget />
</div>
);
}Example 2: Dashboard Page
import { useChatContext } from '@cyborg-sdk/react';
function DashboardPage() {
const { stats, recentData } = useDashboard();
useChatContext({
pageData: {
currentPage: '/dashboard',
description: 'User analytics dashboard',
widgets: ['overview-stats', 'charts', 'recent-activity', 'goals'],
stats: {
totalRevenue: stats.revenue,
activeUsers: stats.users,
conversionRate: stats.conversion,
monthOverMonth: stats.growth,
},
},
sessionData: {
userPlan: 'premium',
accountAge: '2 years',
features: ['analytics', 'reports', 'automation'],
},
});
return (
<div className="dashboard">
{/* Dashboard content */}
{/* Chat context enables: */}
{/* User: "Why is my revenue down?" */}
{/* AI: "Based on your dashboard, I see your revenue decreased 15% this month..." */}
</div>
);
}Example 3: Documentation Page
import { useChatContext } from '@cyborg-sdk/react';
function DocPage({ slug }) {
const doc = loadDocumentation(slug);
useChatContext({
pageData: {
currentPage: '/docs/' + slug,
description: doc.title,
docTitle: doc.title,
section: doc.section,
topic: doc.topic,
relatedDocs: doc.related,
codeExamples: doc.hasCodeExamples,
widgets: ['toc', 'content', 'code-examples', 'related-docs'],
},
sessionData: {
recentDocs: ['authentication', 'api-setup', 'deployment'],
experience: 'intermediate',
},
});
return (
<article className="documentation">
<h1>{doc.title}</h1>
<div>{doc.content}</div>
{/* Chat context enables: */}
{/* User: "How does this work with React?" */}
{/* AI: "Regarding the {topic} you're reading about..." */}
</article>
);
}Example 4: Multi-User Collaboration
import { useChatContext } from '@cyborg-sdk/react';
function ProjectPage({ projectId }) {
const project = loadProject(projectId);
const teamMembers = loadTeamMembers(projectId);
const currentUser = useCurrentUser();
useChatContext({
pageData: {
currentPage: '/projects/' + projectId,
projectId,
projectName: project.name,
description: `Project: ${project.name}`,
status: project.status,
deadline: project.deadline,
teamSize: teamMembers.length,
widgets: ['team', 'tasks', 'timeline', 'documents'],
},
sessionData: {
userId: currentUser.id,
role: currentUser.roleInProject,
permissions: currentUser.permissions,
joinedDate: currentUser.joinDate,
taskCount: currentUser.assignedTasks.length,
},
});
return (
<div className="project">
<h1>{project.name}</h1>
{/* Project content */}
{/* Chat context enables: */}
{/* "What tasks do I have?" - Considers user's role and permissions */}
{/* "Who's working on X?" - Knows team members */}
{/* "When's the deadline?" - Has context about timeline */}
</div>
);
}Best Practices
1. Call useChatContext at the Right Level
Good: Call at the page/route level
// ✅ Call once per page
function ProductPage() {
useChatContext({ ... });
return <ProductContent />;
}Avoid: Calling in deeply nested components
// ❌ Avoid calling in deeply nested components
function DeepChild() {
useChatContext({ ... }); // Too deep
}2. Update Context When Data Changes
function DashboardPage() {
const [stats, setStats] = useState(null);
useEffect(() => {
// Update context whenever stats change
useChatContext({
pageData: {
currentPage: '/dashboard',
stats: stats, // Will update AI context
},
});
}, [stats]);
return <Dashboard stats={stats} />;
}3. Keep Context Focused
Good: Include relevant information
useChatContext({
pageData: {
currentPage: '/products/123',
productName: 'Laptop',
price: 999,
inStock: true,
},
});Avoid: Including everything
// ❌ Too much data
useChatContext({
pageData: {
...allProductData, // Entire product object
...allUIState, // All component state
...allAnalytics, // All tracking data
},
});4. Use Consistent Key Names
Create a pattern for your keys:
// Good: Consistent naming
{
productId: '123',
productName: 'Laptop',
productPrice: 999,
productCategory: 'Electronics',
}
// Avoid: Inconsistent naming
{
product_id: '123',
name: 'Laptop',
price: 999,
category: 'Electronics',
}5. Provide Readable Descriptions
// Good: Clear descriptions
pageData: {
description: 'Product detail page for wireless headphones',
widgets: ['price', 'specifications', 'reviews', 'similar-products'],
}
// Avoid: Vague descriptions
pageData: {
description: 'product page',
widgets: ['a', 'b', 'c'],
}Advanced Patterns
Dynamic Context Based on User Role
function ProjectDashboard({ projectId }) {
const user = useCurrentUser();
const project = loadProject(projectId);
// Build context based on user role
const contextData = user.role === 'admin'
? {
pageData: {
...projectInfo,
analyticsData: project.analytics,
costBreakdown: project.costs,
teamMetrics: project.teamMetrics,
},
}
: {
pageData: {
...projectInfo,
// Regular users don't see cost/analytics
},
};
useChatContext(contextData);
return <Dashboard />;
}Context for Real-Time Features
function ChatRoom({ roomId }) {
const [messages, setMessages] = useState([]);
const [participants, setParticipants] = useState([]);
// Update context as room state changes
useEffect(() => {
useChatContext({
pageData: {
currentPage: `/chat/${roomId}`,
roomId,
messageCount: messages.length,
participantCount: participants.length,
hasActiveParticipants: participants.some(p => p.online),
},
sessionData: {
joinedAt: Date.now(),
},
});
}, [messages, participants]);
return <ChatRoom />;
}Context with Analytics Integration
function AnalyticsPage() {
const { period, metrics, filters } = useAnalytics();
useChatContext({
pageData: {
currentPage: '/analytics',
selectedPeriod: period,
appliedFilters: filters,
metrics: {
pageViews: metrics.pageViews,
bounceRate: metrics.bounceRate,
avgSessionDuration: metrics.sessionDuration,
conversionRate: metrics.conversion,
},
dataQuality: 'high', // Helps AI trust the data
},
});
return <AnalyticsCharts />;
}Testing Context
To verify your context is being sent correctly:
function TestPage() {
useChatContext({
pageData: {
currentPage: '/test',
testData: 'Hello from context',
},
});
return (
<div>
<p>Send a message to the chat asking about this page.</p>
<p>The AI should mention the test data if context is working.</p>
</div>
);
}Expected chat response:
"I see you're on a test page with test data 'Hello from context'. How can I help?"
Common Questions
Q: How much context can I send?
A: There's no hard limit, but keep it reasonable. Aim for 100-1000 characters per request. Excessive data may slow down responses.
Q: Does context persist between pages?
A: No, context is page-specific. Each time the user navigates, call useChatContext() again with new data.
Q: Can I send sensitive data in context?
A: The chat history with context is stored on our servers. Don't send PII, passwords, or sensitive secrets. See Security Best Practices.
Q: What if I don't call useChatContext?
A: Chat still works! It just won't have page context, so responses will be more generic.
Q: Can I update context without changing pages?
A: Yes! Call useChatContext() again whenever data changes on the same page.
Next Steps
- Review Security Best Practices - Understand what data to share
- Explore useChatContext API - Full API reference
- Upload Documentation - Improve context with your docs
- View Configuration Options - Advanced settings
Related Documentation
- useChatContext Hook Reference - API documentation
- Security Best Practices - What data to share safely
- React SDK Guide - SDK overview