
Syncfusion React Ai Assistview
- 444 installs
- 3 repo stars
- Updated July 28, 2026
- syncfusion/react-ui-components-skills
syncfusion-react-ai-assistview is a Syncfusion agent skill that generates React AIAssistViewComponent code with promptRequest handlers, toolbars, and conversation history for developers embedding generative AI assistant
About
syncfusion-react-ai-assistview is a component-specific skill from syncfusion/react-ui-components-skills for building React AI assistant interfaces with Syncfusion's AI AssistView component. The skill covers AIAssistViewComponent from @syncfusion/ej2-react-interactive-chat, promptRequest event handlers to connect generative AI services, toolbar commands, prompt suggestions, streaming responses, and prompts collection for conversation history. Developers reach for this skill when adding chat-style AI help panels to admin portals, SaaS dashboards, or internal tools without inventing incorrect Syncfusion props. Install via npx skills add syncfusion/react-ui-components-skills so the agent reads SKILL.md patterns and references/ guides before generating production-ready assistant UI code.
- syncfusion-react-ai-assistview
Syncfusion React Ai Assistview by the numbers
- 444 all-time installs (skills.sh)
- +53 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #979 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-ai-assistviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 444 |
|---|---|
| repo stars | ★ 3 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/react-ui-components-skills ↗ |
How do you add a Syncfusion React AI assistant UI?
Use syncfusion-react-ai-assistview for development tasks
Who is it for?
React developers integrating Syncfusion ej2-react-interactive-chat who need an agent-guided AI assistant panel with prompts, toolbars, and streaming responses.
Skip if: Skip syncfusion-react-ai-assistview when building a custom headless LLM API integration without Syncfusion UI components.
When should I use this skill?
Adding a Syncfusion AI AssistView chat panel, prompt toolbar, or generative AI assistant interface to a React application.
What you get
React AIAssistViewComponent code with promptRequest wiring, toolbar config, and prompts collection for conversation history
- React AIAssistViewComponent integration code
Files
Syncfusion React AI AssistView Component
Component Overview
The Syncfusion React AI AssistView component is a comprehensive interactive chat component designed for building AI-powered conversational interfaces. It provides:
Core Capabilities
- Prompt-Response Management: Manage conversation history with automatic data collection
- Real-time Streaming: Stream AI responses character-by-character for live typing effects
- Template System: Customize every UI element (banners, prompt items, responses, suggestions, footer)
- Multi-View Support: Switch between conversation assist view and custom content views
- Voice Integration: Built-in Speech-to-Text (voice input) and Text-to-Speech (voice output)
- File Attachments: Upload and include files with prompts
- Advanced Toolbars: Configurable toolbars for header, footer, responses, and prompts
- AI Service Integration: Direct integration with OpenAI, Azure OpenAI, and other AI services
- Event-Driven Architecture: Hooks for prompt submission, changes, and component lifecycle
Key Features
- Markdown Support: Render AI responses as formatted HTML via markdown parsing
- Conversation History: Automatic tracking of all prompts and responses
- Suggestion System: Display helpful prompt suggestions to guide users
- Avatar Customization: Customize user and AI icons/avatars
- Scroll Management: Auto-scroll or manual scroll-to-bottom button
- Clear Functionality: Clear current prompt or entire conversation
- Responsive Design: Works on desktop and mobile with responsive layouts
Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Install @syncfusion/ej2-react-interactive-chat package
- Add CSS theme imports
- Create basic component initialization
- Render component to DOM
- First working functional component example
Configuration Essentials
📄 Read: references/configuration-essentials.md
- Set initial prompt text and placeholders
- Configure prompt suggestions and suggestion headers
- Customize user and AI avatar icons
- Control clear button visibility
- Enable/disable scroll-to-bottom functionality
- Manage component instance via refs
- Set component dimensions (height and width)
- Apply custom CSS classes for styling
- Control header visibility
- Configure globalization (locale, RTL support)
- Enable state persistence across sessions
Conversation Management
📄 Read: references/conversation-management.md
- Initialize with pre-configured conversation data
- Add responses (string or object format)
- Access and manage conversation history
- Work with PromptModel data structure
- Render markdown in responses
- Persist and restore conversations
Events and Interactions
📄 Read: references/events-and-interactions.md
- Handle component lifecycle (created event)
- Respond to prompt submissions (promptRequest event)
- Track prompt text changes (promptChanged event)
- Access detailed event arguments (PromptChangedEventArgs, PromptRequestEventArgs)
- Cancel prompt submissions programmatically
- Handle stop responding events for long operations
- Modify suggestions and toolbar items dynamically
- Implement event-driven workflows
- Integrate with AI services via event handlers
Toolbar Customization
📄 Read: references/toolbar-customization.md
- Configure four toolbar types (header, footer, response, prompt)
- Add custom toolbar items
- Control toolbar positioning (Inline vs Bottom)
- Customize toolbar icons
- Handle item click events
- Configure all ToolbarItemModel properties (align, cssClass, disabled, tabIndex, template, type, visible)
- Create custom toolbar item templates
- Control item visibility and enabled state dynamically
- Set tab order for keyboard navigation
- Manage attachment button behavior
File Attachments
📄 Read: references/file-attachments.md
- Enable file attachment support
- Configure upload endpoints (saveUrl, removeUrl)
- Restrict file types (allowedFileType)
- Set file size limits (maxFileSize)
- Limit number of attachments (maximumCount)
- Access attached files via attachedFiles array (FileInfo interface)
- Handle attachment lifecycle events (beforeAttachmentUpload, attachmentUploadSuccess, attachmentUploadFailure, attachmentRemoved)
- Validate files before upload
- Initialize prompts with pre-attached files
- Handle server-side file processing
Custom Views
📄 Read: references/custom-views.md
- Create multiple views (Assist and Custom types)
- Set view names and icons
- Define view-specific templates
- Configure activeView property to set initial view
- Switch between views programmatically
- Persist active view across sessions
- Conditionally set initial view based on user role or state
- Display side-by-side content panels
- Use cases for multi-view layouts
Templating System
📄 Read: references/templating-system.md
- Customize banner templates (welcome content)
- Create prompt item templates (user message display)
- Design response item templates (AI response display)
- Build suggestion item templates
- Create custom footer templates
- Access template context data
AI Service Integration
📄 Read: references/ai-integration-setup.md
- Integrate with Azure OpenAI, OpenAI, Gemini, Claude
- Configure API credentials and authentication
- Handle real-time prompt processing
- Stream responses for live typing effects
- Parse markdown responses with marked library
- Error handling and rate limiting
- Security considerations for API keys
Speech Capabilities
📄 Read: references/speech-capabilities.md
- Enable Speech-to-Text (voice input)
- Configure speech recognition language
- Handle interim transcripts while speaking
- Implement Text-to-Speech (voice output)
- Customize button labels and icons
- Handle speech events (start, stop, transcript, error)
- Browser compatibility notes
Methods and APIs
📄 Read: references/methods-and-apis.md
- Use addPromptResponse() method
- Execute prompts dynamically with executePrompt()
- Scroll to bottom programmatically
- Access component instance via refs
- Manage component state
- Common patterns and gotchas
---
Quick Start Example
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const assistInstance = React.useRef<AIAssistViewComponent>(null);
const onPromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
let defaultResponse = 'For real-time AI processing, connect to your preferred service (OpenAI, Azure OpenAI, etc.).';
assistInstance.current.addPromptResponse(defaultResponse);
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={onPromptRequest}
prompt={'Welcome! How can I help?'}
promptSuggestions={['Ask about features', 'Get started guide']}
/>
);
}
ReactDOM.render(<App />, document.getElementById('container'));---
Common Patterns
Pattern 1: Basic Chat with Suggestions
Create a simple conversational interface with predefined suggestions:
- Enable prompt suggestions to guide user interactions
- Handle promptRequest event with simple responses
- Display conversation history automatically
Pattern 2: AI Service Integration
Connect to real AI services for intelligent responses:
- Use promptRequest event to capture user input
- Call AI API with prompt text
- Stream response character-by-character for live effect
- Parse markdown responses for formatted output
Pattern 3: Multi-View Dashboard
Combine chat with supporting content:
- Create Assist view for conversation
- Add Custom view for settings/sidebar
- Switch activeView based on user interaction
- Share data between views
Pattern 4: Voice-Enabled Chat
Enable hands-free interaction with speech:
- Enable speechToTextSettings to capture voice
- Configure Text-to-Speech for response audio
- Use toolbar for voice control buttons
- Handle speech events for status feedback
Pattern 5: File-Attached Prompts
Support file uploads with prompts:
- Enable attachments with enableAttachments property
- Configure attachment endpoints and file restrictions
- Include file data in prompt context
- Send files to backend API
---
Key Props & Configuration
Essential Props
promptRequest: Event handler when user submits promptprompt: Initial/default text in prompt inputpromptPlaceholder: Placeholder text for input areapromptSuggestions: Array of suggested promptsprompts: Pre-configured conversation data
Customization Props
promptIconCss: CSS class for user avatarresponseIconCss: CSS class for AI avatarshowClearButton: Show/hide clear button (default: false)showHeader: Show/hide component header (default: true)enableScrollToBottom: Show scroll-to-bottom button (default: true)height: Component height (string | number, default: '100%')width: Component width (string | number, default: '100%')cssClass: Custom CSS classes for stylingactiveView: Currently displayed view index (number, default: 0)
Template Props
bannerTemplate: Welcome banner contentpromptItemTemplate: User message displayresponseItemTemplate: AI response displaypromptSuggestionItemTemplate: Suggestion stylingfooterTemplate: Custom prompt input area
Advanced Props
enableAttachments: Enable file uploads (default: false)attachmentSettings: File upload configurationspeechToTextSettings: Voice input configurationtoolbarSettings: Header toolbar configurationfooterToolbarSettings: Footer toolbar configurationresponseToolbarSettings: Response action toolbarpromptToolbarSettings: Prompt toolbar configurationlocale: Localization/globalization setting (default: 'en-US')enableRtl: Enable right-to-left rendering (default: false)enablePersistence: Enable state persistence (default: false)
Event Props
created: Component lifecycle eventpromptRequest: Prompt submission eventpromptChanged: Prompt text change eventstopRespondingClick: Stop button click eventbeforeAttachmentUpload: Before file upload eventattachmentUploadSuccess: File upload success eventattachmentUploadFailure: File upload failure eventattachmentRemoved: File removal event
---
Common Use Cases
Chat Bot with AI Integration
Build a customer service chatbot connected to OpenAI or Azure services: 1. Set up component with suggestions 2. Handle promptRequest to send to AI API 3. Stream responses for real-time feedback 4. Use templates for branded appearance
Voice-Enabled Assistant
Create hands-free voice interaction: 1. Enable speechToTextSettings 2. Configure Text-to-Speech toolbar button 3. Handle speech events for status 4. Provide visual feedback during voice capture
File Analysis Chat
Allow users to upload and discuss files: 1. Enable attachments 2. Configure file restrictions (type, size, count) 3. Send files with prompts to backend 4. Display file information in conversation
Multi-Feature Dashboard
Combine chat with settings and content: 1. Create multiple views (Assist + Custom) 2. Use templates for custom view content 3. Implement view switching logic 4. Share conversation state between views
---
AI Integration Setup
Table of Contents
- AI Service Overview
- Azure OpenAI Setup
- API Credentials Configuration
- Real-Time Prompt Processing
- Stream Response Handling
- Markdown Response Parsing
- Error Handling
- Rate Limiting and Optimization
- Security Considerations
AI Service Overview
The AI AssistView can integrate with various AI services:
- Azure OpenAI: Microsoft's hosted OpenAI service
- OpenAI: Direct API access to GPT models
- Google Gemini: Google's advanced AI model
- Anthropic Claude: Constitutional AI models
- Custom APIs: Any REST-based AI service
Azure OpenAI Setup
Prerequisites
1. Azure account with OpenAI resource created 2. API key and endpoint from Azure portal 3. Deployed model (e.g., gpt-4, gpt-3.5-turbo) 4. API version (e.g., 2024-02-01)
Getting Azure OpenAI Credentials
// Log into Azure Portal → Azure OpenAI → Resource
// Under "Keys and endpoint":
const azureOpenAIApiKey = 'Your_API_Key_Here';
const azureOpenAIEndpoint = 'https://your-resource.openai.azure.com/';
const azureOpenAIApiVersion = '2024-02-01';
const azureDeploymentName = 'gpt-35-turbo'; // or your deploymentAPI Credentials Configuration
Secure Credential Management
Never expose API keys in client-side code in production!
// ❌ WRONG - Exposes API key
const apiKey = 'sk-abc123...'; // DANGEROUS!
// ✅ CORRECT - Use environment variables
const apiKey = process.env.REACT_APP_OPENAI_KEY;
// ✅ BETTER - Use backend proxy
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ prompt: userPrompt })
});Environment Variable Setup
Create .env.local file:
REACT_APP_OPENAI_API_KEY=your_key_here
REACT_APP_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
REACT_APP_OPENAI_DEPLOYMENT=gpt-35-turboAccess in React:
const apiKey = process.env.REACT_APP_OPENAI_API_KEY;
const endpoint = process.env.REACT_APP_OPENAI_ENDPOINT;Real-Time Prompt Processing
Basic Prompt-Response Flow
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
// Call AI service with user prompt
const response = await fetch(
`${process.env.REACT_APP_OPENAI_ENDPOINT}/openai/deployments/${process.env.REACT_APP_OPENAI_DEPLOYMENT}/chat/completions?api-version=${process.env.REACT_APP_OPENAI_API_VERSION}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': process.env.REACT_APP_OPENAI_API_KEY!
},
body: JSON.stringify({
messages: [{ role: 'user', content: args.prompt }],
temperature: 0.7,
max_tokens: 500
})
}
);
const data = await response.json();
const aiResponse = data.choices[0].message.content;
// Display response
assistInstance.current?.addPromptResponse(aiResponse);
} catch (error) {
assistInstance.current?.addPromptResponse('Error: Unable to process request');
console.error('AI API error:', error);
}
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Stream Response Handling
Streaming Responses from AI
Enable real-time typing effect:
import { marked } from 'marked';
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
const response = await fetch(
`${endpoint}/openai/deployments/${deployment}/chat/completions?api-version=${apiVersion}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': apiKey
},
body: JSON.stringify({
messages: [{ role: 'user', content: args.prompt }],
stream: true // Enable streaming
})
}
);
const reader = response.body.getReader();
let fullResponse = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
// Decode and parse streaming chunks
const chunk = new TextDecoder().decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6));
const content = data.choices[0].delta?.content;
if (content) {
fullResponse += content;
// Update UI with partial response
const htmlResponse = marked.parse(fullResponse);
assistInstance.current?.addPromptResponse(
htmlResponse,
false // Not final yet
);
}
} catch (e) {
// Handle parse errors silently
}
}
}
}
// Mark as final when complete
assistInstance.current?.addPromptResponse(
marked.parse(fullResponse),
true // Final response
);
} catch (error) {
assistInstance.current?.addPromptResponse('Error streaming response');
console.error('Streaming error:', error);
}
};Markdown Response Parsing
Install and Configure Marked
npm install marked --saveConvert Markdown to HTML
import { marked } from 'marked';
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
const response = await getAIResponse(args.prompt);
// Response is markdown from AI
const htmlResponse = marked.parse(response);
// Display formatted HTML
assistInstance.current?.addPromptResponse(htmlResponse);
} catch (error) {
console.error('Error:', error);
}
};Markdown to HTML Example
const markdownText = `
## Response Title
This is **bold** and this is *italic*.
- Bullet point 1
- Bullet point 2
\`\`\`javascript
const example = "code block";
\`\`\`
[Link](https://example.com)
`;
const htmlResponse = marked.parse(markdownText);
// Displays formatted HTML with headings, lists, code blocks, etc.Error Handling
Comprehensive Error Handling
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
// Validate input
if (!args.prompt?.trim()) {
assistInstance.current?.addPromptResponse('Please enter a prompt');
return;
}
// Show loading state
assistInstance.current?.addPromptResponse('Processing...');
// Call AI service
const response = await fetch(aiEndpoint, {
method: 'POST',
headers: { 'api-key': apiKey },
body: JSON.stringify({ messages: [{ role: 'user', content: args.prompt }] })
});
// Handle HTTP errors
if (!response.ok) {
if (response.status === 401) {
throw new Error('Authentication failed');
} else if (response.status === 429) {
throw new Error('Rate limit exceeded. Please try again later');
} else {
throw new Error(`API error: ${response.statusText}`);
}
}
const data = await response.json();
const aiResponse = data.choices[0].message.content;
assistInstance.current?.addPromptResponse(aiResponse);
} catch (error: any) {
// Show user-friendly error message
const errorMessage = error instanceof Error
? error.message
: 'An unexpected error occurred';
assistInstance.current?.addPromptResponse(
`<div class="error-message">⚠️ ${errorMessage}</div>`
);
// Log for debugging
console.error('Prompt handling error:', error);
}
};API-Specific Error Handling
const handleAzureOpenAIError = (response: Response, data: any) => {
if (data.error?.code === 'AuthenticationFailed') {
return 'Invalid API key. Please check your credentials.';
} else if (data.error?.code === 'DeploymentNotFound') {
return 'Model deployment not found. Check deployment name.';
} else if (data.error?.code === 'RequestTooLarge') {
return 'Prompt is too long. Please make it shorter.';
} else if (response.status === 429) {
return 'Too many requests. Please wait a moment.';
} else {
return `Error: ${data.error?.message || 'Unknown error'}`;
}
};Rate Limiting and Optimization
Implement Request Throttling
import { useRef } from 'react';
function App() {
const lastRequestTime = useRef<number>(0);
const requestDelay = 500; // Minimum 500ms between requests
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
const now = Date.now();
// Throttle requests
if (now - lastRequestTime.current < requestDelay) {
assistInstance.current?.addPromptResponse('Please wait before sending another prompt');
return;
}
lastRequestTime.current = now;
// Process prompt
try {
const response = await getAIResponse(args.prompt);
assistInstance.current?.addPromptResponse(response);
} catch (error) {
console.error('Error:', error);
}
};
return (
<AIAssistViewComponent
id="aiAssistView"
promptRequest={handlePromptRequest}
/>
);
}Token Optimization
// Limit response length to reduce token usage
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
const response = await fetch(aiEndpoint, {
method: 'POST',
headers: { 'api-key': apiKey },
body: JSON.stringify({
messages: [{ role: 'user', content: args.prompt }],
max_tokens: 300, // Limit response length
temperature: 0.7 // Control creativity
})
});
// ... handle response
};Security Considerations
Backend Proxy Pattern (Recommended)
// Client-side: Call your backend
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: args.prompt })
});
const data = await response.json();
assistInstance.current?.addPromptResponse(data.response);
};
// Server-side (Node.js/Express):
app.post('/api/chat', async (req, res) => {
const { prompt } = req.body;
// API key stays on server
const response = await fetch('https://api.openai.com/...', {
headers: { 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` },
body: JSON.stringify({ messages: [{ role: 'user', content: prompt }] })
});
const data = await response.json();
res.json({ response: data.choices[0].message.content });
});Input Validation
const validatePrompt = (prompt: string): boolean => {
// Check length
if (prompt.length > 2000) return false;
// Check for malicious patterns
if (prompt.includes('<script>')) return false;
if (prompt.includes('javascript:')) return false;
// Check for injection attempts
if (prompt.toLowerCase().includes('ignore previous')) return false;
return true;
};
const handlePromptRequest = (args: PromptRequestEventArgs) => {
if (!validatePrompt(args.prompt)) {
assistInstance.current?.addPromptResponse('Invalid prompt');
return;
}
// Safe to process
processPrompt(args.prompt);
};Complete Integration Example
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import { marked } from 'marked';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
if (!args.prompt?.trim()) {
assistInstance.current?.addPromptResponse('Please enter a prompt');
return;
}
try {
// Show loading
assistInstance.current?.addPromptResponse('Processing your request...');
// Call backend API (not direct AI API)
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: args.prompt })
});
if (!response.ok) {
throw new Error('API request failed');
}
const data = await response.json();
// Parse and display response
const htmlResponse = marked.parse(data.response);
assistInstance.current?.addPromptResponse(htmlResponse);
} catch (error) {
assistInstance.current?.addPromptResponse(
'⚠️ Error processing request. Please try again.'
);
console.error('Error:', error);
}
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
prompt="Ask me anything!"
promptSuggestions={[
'What can you help with?',
'Tell me about AI',
'How do I get started?'
]}
/>
);
}
export default App;Best Practices Summary
✅ Use backend proxy for API credentials ✅ Implement request throttling ✅ Parse responses as markdown ✅ Handle all error cases gracefully ✅ Validate user input ✅ Implement streaming for long responses ✅ Log errors for debugging ✅ Show loading states ✅ Optimize token usage ✅ Use environment variables for configuration
Configuration Essentials
Prompt Text and Placeholder
Setting Default Prompt Text
Use the prompt property to set initial or default text in the prompt input area:
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
prompt="What tools can help me prioritize tasks?"
/>
);
}
export default App;Setting Placeholder Text
The promptPlaceholder property defines the placeholder text displayed when the input is empty. Default is "Type prompt for assistance...":
<AIAssistViewComponent
id="aiAssistView"
promptPlaceholder="Ask me anything..."
/>Prompt Suggestions Configuration
Basic Suggestions
The promptSuggestions property provides users with helpful suggestions as starting prompts:
const suggestions = [
"Best practices for writing clean code?",
"How to optimize code editor?",
"Tips for better performance?"
];
<AIAssistViewComponent
id="aiAssistView"
promptSuggestions={suggestions}
/>Customizing Suggestions Header
Add a header label above suggestions using promptSuggestionsHeader:
<AIAssistViewComponent
id="aiAssistView"
promptSuggestions={suggestions}
promptSuggestionsHeader="Suggested Prompts"
/>Handling Suggestion Selection
When users click a suggestion, it triggers the promptRequest event:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// args.prompt contains the suggestion text
console.log('Selected suggestion:', args.prompt);
};
<AIAssistViewComponent
id="aiAssistView"
promptSuggestions={suggestions}
promptRequest={handlePromptRequest}
/>Avatar Customization
User Avatar (promptIconCss)
Customize the icon that appears with user prompts using CSS classes:
<AIAssistViewComponent
id="aiAssistView"
promptIconCss="e-icons e-user"
/>AI Response Avatar (responseIconCss)
Customize the icon that appears with AI responses. Default is e-assistview-icon:
<AIAssistViewComponent
id="aiAssistView"
promptIconCss="e-icons e-user"
responseIconCss="e-icons e-bullet-4"
/>Available Icon Classes
Common Syncfusion icon classes:
e-user- User profile icone-bot- Robot/bot icone-comment-show- Comment icone-circle-info- Info icone-assistview-icon- Default AI icone-bullet-4- Bullet point- Custom CSS class for custom SVG/image icons
Custom Avatar Example
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const onPromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response text');
}, 1000);
};
return (
<>
<style>{`
.custom-user-icon::before {
content: '👤';
font-size: 18px;
}
.custom-ai-icon::before {
content: '🤖';
font-size: 18px;
}
`}</style>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={onPromptRequest}
promptIconCss="custom-user-icon"
responseIconCss="custom-ai-icon"
/>
</>
);
}
export default App;Clear Button Visibility
Enable Clear Button
The showClearButton property controls whether a clear button appears in the prompt input area. Default is false:
<AIAssistViewComponent
id="aiAssistView"
showClearButton={true}
/>Clear Button Behavior
When clicked, the clear button only clears the current prompt text, NOT the conversation history:
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response to: ' + args.prompt);
}, 1000);
};
const clearConversation = () => {
// Manually clear all prompts/responses
if (assistInstance.current) {
assistInstance.current.prompts = [];
}
};
return (
<div>
<button onClick={clearConversation}>Clear All</button>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
showClearButton={true}
/>
</div>
);
}
export default App;Scroll to Bottom Functionality
Enable Scroll Button
The enableScrollToBottom property controls the scroll-to-bottom indicator. Default is true:
<AIAssistViewComponent
id="aiAssistView"
enableScrollToBottom={true}
/>When It Appears
A floating scroll-to-bottom button appears when:
- User scrolls away from the bottom of the conversation
- New responses are added while user is viewing earlier messages
Clicking the button smoothly scrolls to the latest response.
Disable Auto-Scroll
If you want to hide the scroll button but keep scrolling behavior:
<AIAssistViewComponent
id="aiAssistView"
enableScrollToBottom={false}
/>Component Sizing and Layout
Setting Component Dimensions
Control the size of the AI AssistView component using height and width properties:
Type: string | number Default: height='100%', width='100%'
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
height="600px"
width="800px"
/>
);
}
export default App;Height Options
// Fixed pixel height
height="500px"
// Percentage height (relative to container)
height="100%"
// Viewport height
height="80vh"
// Numeric value (interpreted as pixels)
height={600}Width Options
// Fixed pixel width
width="1000px"
// Percentage width (relative to container)
width="100%"
// Numeric value (interpreted as pixels)
width={800}
// Auto width
width="auto"Responsive Sizing
Make the component responsive to different screen sizes:
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React, { useState, useEffect } from 'react';
function App() {
const [dimensions, setDimensions] = useState({
height: '600px',
width: '100%'
});
useEffect(() => {
const updateDimensions = () => {
if (window.innerWidth < 768) {
// Mobile
setDimensions({ height: '100vh', width: '100%' });
} else if (window.innerWidth < 1024) {
// Tablet
setDimensions({ height: '70vh', width: '90%' });
} else {
// Desktop
setDimensions({ height: '600px', width: '800px' });
}
};
updateDimensions();
window.addEventListener('resize', updateDimensions);
return () => window.removeEventListener('resize', updateDimensions);
}, []);
return (
<AIAssistViewComponent
id="aiAssistView"
height={dimensions.height}
width={dimensions.width}
/>
);
}
export default App;Full Viewport Layout
Make the component fill the entire viewport:
<AIAssistViewComponent
id="aiAssistView"
height="100vh"
width="100%"
/>Within a Container
Size relative to a parent container:
function App() {
return (
<div style={{ height: '800px', width: '1200px', padding: '20px' }}>
<AIAssistViewComponent
id="aiAssistView"
height="100%"
width="100%"
/>
</div>
);
}Custom CSS Classes
cssClass Property
Apply custom CSS classes to the component root element for additional styling:
Type: string Default: ''
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<>
<style>{`
.custom-ai-chat {
border: 2px solid #667eea;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.custom-ai-chat .e-toolbar {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.custom-ai-chat .e-prompt-input {
font-size: 16px;
padding: 12px;
}
`}</style>
<AIAssistViewComponent
id="aiAssistView"
cssClass="custom-ai-chat"
/>
</>
);
}
export default App;Multiple CSS Classes
Apply multiple classes separated by spaces:
<AIAssistViewComponent
id="aiAssistView"
cssClass="custom-theme dark-mode elevated-card"
/>Theme Customization with cssClass
Create custom themes:
<style>{`
/* Light theme */
.theme-light {
background-color: #ffffff;
color: #333333;
}
.theme-light .e-prompt-area {
background-color: #f5f5f5;
}
/* Dark theme */
.theme-dark {
background-color: #1e1e1e;
color: #ffffff;
}
.theme-dark .e-prompt-area {
background-color: #2d2d2d;
}
.theme-dark .e-prompt-input {
background-color: #2d2d2d;
color: #ffffff;
}
/* Accent colors */
.accent-blue .e-toolbar {
background-color: #2196F3;
}
.accent-purple .e-toolbar {
background-color: #9C27B0;
}
.accent-green .e-toolbar {
background-color: #4CAF50;
}
`}</style>
function App() {
const [theme, setTheme] = useState('theme-light accent-blue');
return (
<div>
<select onChange={(e) => setTheme(e.target.value)}>
<option value="theme-light accent-blue">Light Blue</option>
<option value="theme-dark accent-purple">Dark Purple</option>
<option value="theme-light accent-green">Light Green</option>
</select>
<AIAssistViewComponent
id="aiAssistView"
cssClass={theme}
/>
</div>
);
}Spacing and Layout Adjustments
<style>{`
.compact-layout {
font-size: 14px;
}
.compact-layout .e-prompt-item,
.compact-layout .e-response-item {
padding: 8px;
margin: 4px 0;
}
.spacious-layout {
font-size: 16px;
}
.spacious-layout .e-prompt-item,
.spacious-layout .e-response-item {
padding: 16px;
margin: 12px 0;
}
`}</style>
<AIAssistViewComponent
id="aiAssistView"
cssClass="spacious-layout"
/>Brand-Specific Styling
<style>{`
.company-branded {
--primary-color: #FF6B6B;
--secondary-color: #4ECDC4;
--text-color: #2C3E50;
}
.company-branded .e-toolbar {
background-color: var(--primary-color);
color: white;
}
.company-branded .e-btn-primary {
background-color: var(--secondary-color);
border-color: var(--secondary-color);
}
.company-branded .e-response-item {
border-left: 3px solid var(--primary-color);
}
`}</style>
<AIAssistViewComponent
id="aiAssistView"
cssClass="company-branded"
/>Combining with Syncfusion Themes
// Import Syncfusion theme
import '@syncfusion/ej2-base/styles/material.css';
import '@syncfusion/ej2-react-interactive-chat/styles/material.css';
<AIAssistViewComponent
id="aiAssistView"
cssClass="custom-enhancements" // Add your custom styles on top
/>Header Visibility Control
showHeader Property
Control whether the header is displayed in the component:
Type: boolean Default: true
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
showHeader={false} // Hide the header
/>
);
}
export default App;When to Hide Header
Hide the header when:
- Embedding in a dashboard with its own title
- Creating a minimalist chat interface
- Component is in a modal or sidebar
- You want maximum space for conversation
function MinimalistChat() {
return (
<div className="chat-container">
<h2 className="custom-title">AI Assistant</h2>
<AIAssistViewComponent
id="aiAssistView"
showHeader={false}
height="calc(100vh - 80px)"
/>
</div>
);
}Dynamic Header Toggle
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React, { useState } from 'react';
function App() {
const [headerVisible, setHeaderVisible] = useState(true);
return (
<div>
<button onClick={() => setHeaderVisible(!headerVisible)}>
{headerVisible ? 'Hide Header' : 'Show Header'}
</button>
<AIAssistViewComponent
id="aiAssistView"
showHeader={headerVisible}
/>
</div>
);
}
export default App;Component Instance Management via Refs
Using useRef to Access Component
Use React's useRef hook to access the component instance and call methods:
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Access component methods and properties
console.log('Current prompts:', assistInstance.current?.prompts);
assistInstance.current?.addPromptResponse('Response');
};
const executeCustomPrompt = () => {
// Programmatically execute a prompt
assistInstance.current?.executePrompt('Custom prompt text');
};
return (
<div>
<button onClick={executeCustomPrompt}>Execute Prompt</button>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
/>
</div>
);
}
export default App;Complete Configuration Example
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const prompts = [
"What is AI?",
"How to optimize code?",
"Best practices?"
];
const handlePromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
let response = 'Default response';
if (args.prompt.includes('AI')) {
response = 'AI stands for Artificial Intelligence.';
}
assistInstance.current?.addPromptResponse(response);
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
prompt="How can I help you?"
promptPlaceholder="Enter your question here..."
promptSuggestions={prompts}
promptSuggestionsHeader="Try asking about:"
promptIconCss="e-icons e-user"
responseIconCss="e-icons e-assistview-icon"
showClearButton={true}
enableScrollToBottom={true}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Globalization and Localization
Locale Property
The locale property sets the culture and language for the component. It overrides the global culture setting.
Type: string Default: 'en-US' (English - United States)
import { AIAssistViewComponent, L10n } from '@syncfusion/ej2-react-interactive-chat';
import { loadCldr, setCulture, setCurrencyCode } from '@syncfusion/ej2-base';
import React from 'react';
// Load culture data (required for non-English locales)
// import numberingSystems from 'cldr-data/supplemental/numberingSystems.json';
// import gregorian from 'cldr-data/main/de/ca-gregorian.json';
// import numbers from 'cldr-data/main/de/numbers.json';
// import timeZoneNames from 'cldr-data/main/de/timeZoneNames.json';
// loadCldr(numberingSystems, gregorian, numbers, timeZoneNames);
// Set localized text
L10n.load({
'de': {
'aiassistview': {
'placeholder': 'Geben Sie Ihre Nachricht ein...',
'send': 'Senden',
'clear': 'Löschen',
'copy': 'Kopieren',
'like': 'Gefällt mir',
'dislike': 'Gefällt mir nicht'
}
}
});
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
locale="de" // German locale
/>
);
}
export default App;Common Locale Values
locale="en-US" // English - United States (default)
locale="en-GB" // English - United Kingdom
locale="de-DE" // German - Germany
locale="fr-FR" // French - France
locale="es-ES" // Spanish - Spain
locale="it-IT" // Italian - Italy
locale="ja-JP" // Japanese - Japan
locale="zh-CN" // Chinese - Simplified
locale="zh-TW" // Chinese - Traditional
locale="ko-KR" // Korean - Korea
locale="pt-BR" // Portuguese - Brazil
locale="ar-SA" // Arabic - Saudi Arabia
locale="ru-RU" // Russian - RussiaSpanish Localization Example
import { AIAssistViewComponent, L10n } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
L10n.load({
'es': {
'aiassistview': {
'placeholder': 'Escribe tu mensaje aquí...',
'send': 'Enviar',
'clear': 'Borrar',
'copy': 'Copiar',
'like': 'Me gusta',
'dislike': 'No me gusta',
'promptSuggestionsHeader': 'Sugerencias'
}
}
});
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
locale="es"
promptPlaceholder="Escribe tu pregunta..."
promptSuggestionsHeader="Prueba preguntar:"
promptSuggestions={[
'¿Qué puedes hacer?',
'Ayúdame con algo',
'¿Cómo empiezo?'
]}
/>
);
}
export default App;Dynamic Locale Switching
import { AIAssistViewComponent, L10n } from '@syncfusion/ej2-react-interactive-chat';
import React, { useState } from 'react';
// Load multiple locales
L10n.load({
'en': {
'aiassistview': {
'placeholder': 'Type your message...',
'send': 'Send'
}
},
'fr': {
'aiassistview': {
'placeholder': 'Tapez votre message...',
'send': 'Envoyer'
}
},
'de': {
'aiassistview': {
'placeholder': 'Geben Sie Ihre Nachricht ein...',
'send': 'Senden'
}
}
});
function App() {
const [currentLocale, setCurrentLocale] = useState('en');
return (
<div>
<select value={currentLocale} onChange={(e) => setCurrentLocale(e.target.value)}>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
</select>
<AIAssistViewComponent
id="aiAssistView"
locale={currentLocale}
/>
</div>
);
}
export default App;Right-to-Left (RTL) Support
enableRtl Property
Enable right-to-left rendering for RTL languages (Arabic, Hebrew, etc.):
Type: boolean Default: false
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
enableRtl={true}
locale="ar-SA" // Arabic locale
promptPlaceholder="اكتب رسالتك هنا..."
/>
);
}
export default App;Arabic Language Example
import { AIAssistViewComponent, L10n } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
L10n.load({
'ar': {
'aiassistview': {
'placeholder': 'اكتب رسالتك...',
'send': 'إرسال',
'clear': 'مسح',
'copy': 'نسخ',
'like': 'إعجاب',
'dislike': 'عدم إعجاب'
}
}
});
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
enableRtl={true}
locale="ar"
promptSuggestions={[
'ماذا يمكنك أن تفعل؟',
'ساعدني في شيء ما',
'كيف أبدأ؟'
]}
/>
);
}
export default App;Hebrew Language Example
L10n.load({
'he': {
'aiassistview': {
'placeholder': 'הקלד את ההודעה שלך...',
'send': 'שלח',
'clear': 'נקה',
'copy': 'העתק'
}
}
});
<AIAssistViewComponent
id="aiAssistView"
enableRtl={true}
locale="he"
/>Dynamic RTL Toggle
import React, { useState } from 'react';
function App() {
const [isRtl, setIsRtl] = useState(false);
const [locale, setLocale] = useState('en');
const toggleRtl = () => {
if (!isRtl) {
setIsRtl(true);
setLocale('ar');
} else {
setIsRtl(false);
setLocale('en');
}
};
return (
<div>
<button onClick={toggleRtl}>
{isRtl ? 'Switch to LTR (English)' : 'Switch to RTL (Arabic)'}
</button>
<AIAssistViewComponent
id="aiAssistView"
enableRtl={isRtl}
locale={locale}
/>
</div>
);
}State Persistence
enablePersistence Property
Enable automatic persistence of component state across browser sessions:
Type: boolean Default: false
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
enablePersistence={true} // Automatically saves and restores state
/>
);
}
export default App;What Gets Persisted
When enablePersistence is enabled, the following state is automatically saved:
- Conversation history (prompts and responses)
- Current prompt text
- Active view index
- Component settings and preferences
Persistence Key
The component uses the id property as the persistence key. Different IDs will have separate persisted states:
// Chat 1 - has its own persisted state
<AIAssistViewComponent
id="chat-support"
enablePersistence={true}
/>
// Chat 2 - has separate persisted state
<AIAssistViewComponent
id="chat-assistant"
enablePersistence={true}
/>Manual State Persistence
For more control, implement custom persistence:
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef, useEffect } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
// Load persisted state on mount
useEffect(() => {
const savedState = localStorage.getItem('ai-chat-state');
if (savedState && assistInstance.current) {
const state = JSON.parse(savedState);
assistInstance.current.prompts = state.prompts || [];
}
}, []);
// Save state on every prompt
const handlePromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response');
// Save state
const state = {
prompts: assistInstance.current?.prompts,
timestamp: new Date().toISOString()
};
localStorage.setItem('ai-chat-state', JSON.stringify(state));
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Clear Persisted State
const clearPersistedData = () => {
// Clear component's persisted data
localStorage.removeItem('aiAssistView'); // Uses component ID as key
// Or clear all localStorage
localStorage.clear();
// Reload to apply
window.location.reload();
};
<button onClick={clearPersistedData}>Clear Saved Data</button>Persistence with Session Storage
Use sessionStorage instead of localStorage for session-only persistence:
import React, { useRef, useEffect } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
useEffect(() => {
// Load from sessionStorage (cleared when browser closes)
const saved = sessionStorage.getItem('chat-session');
if (saved && assistInstance.current) {
assistInstance.current.prompts = JSON.parse(saved);
}
// Save on page unload
const handleUnload = () => {
const prompts = assistInstance.current?.prompts;
sessionStorage.setItem('chat-session', JSON.stringify(prompts));
};
window.addEventListener('beforeunload', handleUnload);
return () => window.removeEventListener('beforeunload', handleUnload);
}, []);
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
/>
);
}Combining All Globalization Features
import { AIAssistViewComponent, L10n } from '@syncfusion/ej2-react-interactive-chat';
import React, { useState } from 'react';
L10n.load({
'ar': {
'aiassistview': {
'placeholder': 'اكتب رسالتك...',
'send': 'إرسال'
}
},
'he': {
'aiassistview': {
'placeholder': 'הקלד הודעה...',
'send': 'שלח'
}
},
'en': {
'aiassistview': {
'placeholder': 'Type message...',
'send': 'Send'
}
}
});
function App() {
const [config, setConfig] = useState({
locale: 'en',
enableRtl: false,
enablePersistence: true
});
const changeLanguage = (lang: string) => {
const rtlLanguages = ['ar', 'he'];
setConfig({
...config,
locale: lang,
enableRtl: rtlLanguages.includes(lang)
});
};
return (
<div>
<select onChange={(e) => changeLanguage(e.target.value)} value={config.locale}>
<option value="en">English</option>
<option value="ar">العربية (Arabic)</option>
<option value="he">עברית (Hebrew)</option>
</select>
<label>
<input
type="checkbox"
checked={config.enablePersistence}
onChange={(e) => setConfig({...config, enablePersistence: e.target.checked})}
/>
Save conversation history
</label>
<AIAssistViewComponent
id="aiAssistView"
locale={config.locale}
enableRtl={config.enableRtl}
enablePersistence={config.enablePersistence}
/>
</div>
);
}
export default App;Configuration Best Practices
Use meaningful default prompts: Set prompt text that guides users Provide clear suggestions: Help users understand what they can ask Consistent avatars: Use recognizable icons for user and AI Show clear buttons: Help users manage conversation state Enable scroll feedback: Especially for long conversations Use refs effectively: For advanced state management and method calls
Conversation Management
Table of Contents
- Prompt-Response Collection
- Initializing Pre-Configured Data
- Accessing Conversation History
- Adding Responses
- PromptModel Data Structure
- Markdown Response Rendering
- Dynamic Content
Prompt-Response Collection
Overview
The AI AssistView component automatically maintains a collection of prompts and responses during a session. The prompts property stores all user interactions:
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// The component automatically adds the prompt to prompts collection
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response text');
}, 1000);
};
const displayHistory = () => {
// Access the conversation history
const conversation = assistInstance.current?.prompts;
console.log('Total exchanges:', conversation?.length);
conversation?.forEach((item, index) => {
console.log(`[${index}] User: ${item.prompt}`);
console.log(`[${index}] AI: ${item.response}`);
});
};
return (
<div>
<button onClick={displayHistory}>Show History</button>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
/>
</div>
);
}
export default App;Initializing Pre-Configured Data
Using the prompts Property
Initialize the component with existing conversation data using the prompts property:
import { AIAssistViewComponent, PromptModel } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
const preConfiguredPrompts: PromptModel[] = [
{
prompt: "What is React?",
response: "React is a JavaScript library for building user interfaces with components."
},
{
prompt: "How do I use hooks?",
response: "Hooks let you use state and React features without writing class components."
}
];
return (
<AIAssistViewComponent
id="aiAssistView"
prompts={preConfiguredPrompts}
/>
);
}
export default App;Complete Pre-Configured Example
import { AIAssistViewComponent, PromptRequestEventArgs, PromptModel } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const initialConversation: PromptModel[] = [
{
prompt: "What is AI?",
response: "<div>AI stands for Artificial Intelligence, enabling machines to mimic human intelligence.</div>"
},
{
prompt: "What can AI do?",
response: "<div>AI can perform tasks like learning, problem-solving, and decision-making.</div>"
}
];
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Handle new user prompts
const found = initialConversation.find(item => item.prompt === args.prompt);
setTimeout(() => {
assistInstance.current?.addPromptResponse(
found ? found.response : 'Default response'
);
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
prompts={initialConversation}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Accessing Conversation History
Get All Prompts and Responses
Access the complete conversation history:
const getConversationSummary = () => {
const prompts = assistInstance.current?.prompts;
if (!prompts) return;
// Get conversation statistics
console.log('Total exchanges:', prompts.length);
console.log('First prompt:', prompts[0]?.prompt);
console.log('Last response:', prompts[prompts.length - 1]?.response);
};Filter Conversation Data
Find specific prompts or responses:
const findResponseAbout = (topic: string) => {
const prompts = assistInstance.current?.prompts;
const matching = prompts?.filter(item =>
item.prompt.includes(topic) || item.response.includes(topic)
);
return matching;
};Export Conversation
Save conversation to file or database:
const exportConversation = () => {
const prompts = assistInstance.current?.prompts;
const json = JSON.stringify(prompts, null, 2);
// Save to localStorage
localStorage.setItem('conversation', json);
// Or download as file
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'conversation.json';
link.click();
};Adding Responses
Add Response as String
Append a simple text response to the last prompt:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
// Add response as plain string
assistInstance.current?.addPromptResponse('Simple text response');
}, 1000);
};Add Response as Object
Add a complete prompt-response pair as an object:
const addCompleteExchange = () => {
assistInstance.current?.addPromptResponse({
prompt: "What is React?",
response: "React is a JavaScript library for building user interfaces."
});
};Add HTML Response
Include HTML formatting in responses:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
const htmlResponse = `
<div class="response-content">
<h3>Response Title</h3>
<p>This is a formatted response with <strong>bold text</strong>.</p>
<ul>
<li>Point 1</li>
<li>Point 2</li>
</ul>
</div>
`;
assistInstance.current?.addPromptResponse(htmlResponse);
};PromptModel Data Structure
Properties
The PromptModel interface contains:
interface PromptModel {
prompt: string; // User's question or input
response: string; // AI's response (HTML or plain text)
suggestions?: string[]; // Optional follow-up suggestions
output?: any; // Optional additional data
index?: number; // Position in conversation
}Complete Example
const advancedPrompt: PromptModel = {
prompt: "What is React?",
response: "<div><strong>React</strong> is a JavaScript library...</div>",
suggestions: [
"How to use React?",
"React best practices?",
"React vs Vue?"
],
output: {
confidence: 0.95,
source: "knowledge_base"
}
};
assistInstance.current?.addPromptResponse(advancedPrompt);Markdown Response Rendering
Enable Markdown Parsing
Use the marked library to render markdown as HTML:
npm install marked --saveParse and Display Markdown
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import { marked } from 'marked';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = (args: PromptRequestEventArgs) => {
const markdownResponse = `
## Topic Title
This is **bold** and this is *italic*.
- Bullet point 1
- Bullet point 2
\`\`\`javascript
const code = "example";
\`\`\`
`;
setTimeout(() => {
// Convert markdown to HTML
const htmlResponse = marked.parse(markdownResponse);
assistInstance.current?.addPromptResponse(htmlResponse);
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Dynamic Content
Streaming Responses
Display responses character-by-character for typing effect:
const streamResponse = async (text: string) => {
let displayText = '';
for (let i = 0; i < text.length; i++) {
displayText += text[i];
// Update every 10 characters
if (i % 10 === 0 || i === text.length - 1) {
const htmlResponse = marked.parse(displayText);
assistInstance.current?.addPromptResponse(
htmlResponse,
i === text.length - 1 // Mark as final when complete
);
}
// Add delay for streaming effect
await new Promise(resolve => setTimeout(resolve, 15));
}
};Dynamic Response Update
Add progressive content to responses:
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
// Initial response
assistInstance.current?.addPromptResponse('Thinking...');
// Simulate processing
await new Promise(resolve => setTimeout(resolve, 2000));
// Update with actual content
const fullResponse = 'This is the complete response after processing.';
assistInstance.current?.addPromptResponse(fullResponse);
};Conversation Persistence
Save and restore conversations:
const saveConversation = () => {
const data = {
timestamp: new Date().toISOString(),
prompts: assistInstance.current?.prompts
};
localStorage.setItem('savedChat', JSON.stringify(data));
};
const loadConversation = () => {
const saved = localStorage.getItem('savedChat');
if (saved) {
const data = JSON.parse(saved);
assistInstance.current.prompts = data.prompts;
}
};
const clearConversation = () => {
assistInstance.current.prompts = [];
localStorage.removeItem('savedChat');
};Best Practices
Use HTML responses for rich content: Better formatting and structure Enable markdown parsing: For AI-generated formatted responses Stream long responses: Provides better UX for lengthy content Manage conversation size: Archive old conversations to reduce memory Validate response data: Ensure HTML is safe (XSS prevention) Backup conversations: Save to localStorage or backend regularly
Custom Views
Table of Contents
- Multiple View Architecture
- View Types
- Creating Views with ViewDirective
- Setting View Names
- Customizing View Icons
- View Templates
- Setting Active View
- Switching Between Views
- Use Cases
Multiple View Architecture
The AI AssistView supports multiple views, allowing you to organize different content within the same component:
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent id="aiAssistView">
<ViewsDirective>
<ViewDirective type='Assist'></ViewDirective>
<ViewDirective type='Custom'></ViewDirective>
</ViewsDirective>
</AIAssistViewComponent>
);
}
export default App;View Types
Assist View
The standard conversation view for prompts and responses:
<ViewDirective
type='Assist'
name='Chat'
iconCss='e-assistview-icon'
/>Custom View
A custom content panel for additional features:
<ViewDirective
type='Custom'
name='Settings'
iconCss='e-icons e-settings'
/>Creating Views with ViewDirective
Basic View Setup
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent id="aiAssistView">
<ViewsDirective>
<ViewDirective type='Assist'></ViewDirective>
<ViewDirective type='Custom'></ViewDirective>
</ViewsDirective>
</AIAssistViewComponent>
);
}
export default App;Setting View Names
Name Property
The name property sets the header label for each view:
<AIAssistViewComponent id="aiAssistView">
<ViewsDirective>
<ViewDirective
type='Assist'
name='Conversation'
/>
<ViewDirective
type='Custom'
name='Settings'
/>
<ViewDirective
type='Custom'
name='History'
/>
</ViewsDirective>
</AIAssistViewComponent>Customizing View Icons
Using Icon Classes
Customize view icons with CSS classes:
<AIAssistViewComponent id="aiAssistView">
<ViewsDirective>
<ViewDirective
type='Assist'
name='Chat'
iconCss='e-assistview-icon'
/>
<ViewDirective
type='Custom'
name='Settings'
iconCss='e-icons e-settings'
/>
<ViewDirective
type='Custom'
name='History'
iconCss='e-icons e-history'
/>
</ViewsDirective>
</AIAssistViewComponent>Available Icon Classes
e-assistview-icon - AI Assistant
e-icons e-settings - Settings/gear
e-icons e-history - History
e-icons e-info - Information
e-icons e-help - Help
e-icons e-download - Download
e-icons e-upload - Upload
e-icons e-user - UserCustom Icons
<style>{`
.custom-chat-icon::before { content: '💬'; font-size: 16px; }
.custom-settings-icon::before { content: '⚙️'; font-size: 16px; }
.custom-history-icon::before { content: '📜'; font-size: 16px; }
`}</style>
<ViewDirective
type='Assist'
name='Chat'
iconCss='custom-chat-icon'
/>
<ViewDirective
type='Custom'
name='Settings'
iconCss='custom-settings-icon'
/>View Templates
Setting Custom View Content
The viewTemplate property allows custom HTML content for views:
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
const settingsTemplate = `
<div class="settings-panel">
<h3>Settings</h3>
<div class="setting-item">
<label>Theme:</label>
<select>
<option>Light</option>
<option>Dark</option>
</select>
</div>
<div class="setting-item">
<label>Language:</label>
<select>
<option>English</option>
<option>Spanish</option>
</select>
</div>
</div>
`;
const historyTemplate = `
<div class="history-panel">
<h3>Conversation History</h3>
<div class="history-list">
<p>Previous conversations will appear here</p>
</div>
</div>
`;
return (
<AIAssistViewComponent id="aiAssistView">
<ViewsDirective>
<ViewDirective type='Assist' name='Chat'/>
<ViewDirective
type='Custom'
name='Settings'
iconCss='e-icons e-settings'
viewTemplate={settingsTemplate}
/>
<ViewDirective
type='Custom'
name='History'
iconCss='e-icons e-history'
viewTemplate={historyTemplate}
/>
</ViewsDirective>
</AIAssistViewComponent>
);
}
export default App;Dynamic Template Content
const getSettingsTemplate = (user: any) => {
return `
<div class="settings-panel">
<h3>Settings for ${user.name}</h3>
<div>
<label>Email: ${user.email}</label>
</div>
<div>
<label>Language: ${user.language}</label>
</div>
</div>
`;
};
<ViewDirective
type='Custom'
name='Settings'
viewTemplate={getSettingsTemplate(currentUser)}
/>Setting Active View
ActiveView Property
The activeView property specifies which view is displayed when the component loads. It uses zero-based indexing to refer to views in the order they're defined.
Type: number Default: 0 (first view)
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
return (
<AIAssistViewComponent
id="aiAssistView"
activeView={0} // Show first view (Assist) on load
>
<ViewsDirective>
<ViewDirective type='Assist' name='Chat'/>
<ViewDirective type='Custom' name='Settings'/>
</ViewsDirective>
</AIAssistViewComponent>
);
}
export default App;View Index Values
activeView={0} // First view (index 0)
activeView={1} // Second view (index 1)
activeView={2} // Third view (index 2)
// etc.Setting Initial View on Load
Control which view users see first:
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
// Open directly to Settings view (index 1)
return (
<AIAssistViewComponent
id="aiAssistView"
activeView={1}
>
<ViewsDirective>
<ViewDirective type='Assist' name='Chat' iconCss='e-assistview-icon'/>
<ViewDirective type='Custom' name='Settings' iconCss='e-icons e-settings'/>
<ViewDirective type='Custom' name='History' iconCss='e-icons e-history'/>
</ViewsDirective>
</AIAssistViewComponent>
);
}
export default App;Conditional Initial View
Set initial view based on user preferences or application state:
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React, { useState, useEffect } from 'react';
function App() {
const [initialView, setInitialView] = useState(0);
useEffect(() => {
// Load user's last view from localStorage
const savedView = localStorage.getItem('lastActiveView');
if (savedView) {
setInitialView(parseInt(savedView, 10));
}
}, []);
return (
<AIAssistViewComponent
id="aiAssistView"
activeView={initialView}
>
<ViewsDirective>
<ViewDirective type='Assist' name='Chat'/>
<ViewDirective type='Custom' name='Settings'/>
<ViewDirective type='Custom' name='History'/>
</ViewsDirective>
</AIAssistViewComponent>
);
}
export default App;Dynamic View Selection Based on Role
function App() {
const userRole = getUserRole(); // Your function to get user role
// Admins see settings first, users see chat first
const initialView = userRole === 'admin' ? 1 : 0;
return (
<AIAssistViewComponent
id="aiAssistView"
activeView={initialView}
>
<ViewsDirective>
<ViewDirective type='Assist' name='Chat'/>
<ViewDirective type='Custom' name='Admin Settings'/>
</ViewsDirective>
</AIAssistViewComponent>
);
}Switching Between Views
Programmatic View Switching
Change the active view dynamically using the component reference:
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const switchToSettings = () => {
if (assistInstance.current) {
assistInstance.current.activeView = 1; // Switch to Settings (index 1)
}
};
const switchToChat = () => {
if (assistInstance.current) {
assistInstance.current.activeView = 0; // Switch to Chat (index 0)
}
};
const switchToHistory = () => {
if (assistInstance.current) {
assistInstance.current.activeView = 2; // Switch to History (index 2)
}
};
return (
<div>
<div className="view-switcher">
<button onClick={switchToChat}>Chat</button>
<button onClick={switchToSettings}>Settings</button>
<button onClick={switchToHistory}>History</button>
</div>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
activeView={0}
>
<ViewsDirective>
<ViewDirective type='Assist' name='Chat'/>
<ViewDirective type='Custom' name='Settings'/>
<ViewDirective type='Custom' name='History'/>
</ViewsDirective>
</AIAssistViewComponent>
</div>
);
}
export default App;Switch View with State Persistence
Save the current view when switching:
import { AIAssistViewComponent, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef, useState } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const [currentView, setCurrentView] = useState(0);
const switchView = (viewIndex: number) => {
if (assistInstance.current) {
assistInstance.current.activeView = viewIndex;
setCurrentView(viewIndex);
// Save to localStorage
localStorage.setItem('lastActiveView', viewIndex.toString());
}
};
return (
<div>
<div className="view-tabs">
<button
className={currentView === 0 ? 'active' : ''}
onClick={() => switchView(0)}
>
Chat
</button>
<button
className={currentView === 1 ? 'active' : ''}
onClick={() => switchView(1)}
>
Settings
</button>
<button
className={currentView === 2 ? 'active' : ''}
onClick={() => switchView(2)}
>
History
</button>
</div>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
activeView={currentView}
>
<ViewsDirective>
<ViewDirective type='Assist' name='Chat'/>
<ViewDirective type='Custom' name='Settings'/>
<ViewDirective type='Custom' name='History'/>
</ViewsDirective>
</AIAssistViewComponent>
</div>
);
}
export default App;Conditional View Switching
Switch views based on events or conditions:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Switch to response view after prompt
setTimeout(() => {
assistInstance.current?.addPromptResponse('Processing...');
// Automatically switch to results view
if (assistInstance.current) {
assistInstance.current.activeView = 1; // Switch to results view
}
}, 1000);
};
// Or switch based on user action
const handleToolbarClick = (action: string) => {
if (action === 'settings') {
assistInstance.current.activeView = 1;
} else if (action === 'history') {
assistInstance.current.activeView = 2;
}
};Getting Current Active View
Read the current active view index:
const getCurrentView = () => {
const viewIndex = assistInstance.current?.activeView;
console.log('Current view index:', viewIndex);
const viewNames = ['Chat', 'Settings', 'History'];
console.log('Current view name:', viewNames[viewIndex]);
return viewIndex;
};Complete Multi-View Example
import { AIAssistViewComponent, PromptRequestEventArgs, ViewsDirective, ViewDirective } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const chatViewTemplate = ''; // Default assist view
const settingsTemplate = `
<div class="settings-view">
<h3>Assistant Settings</h3>
<div class="setting">
<label>Tone:</label>
<select>
<option>Formal</option>
<option>Casual</option>
<option>Technical</option>
</select>
</div>
<div class="setting">
<label>Response Length:</label>
<select>
<option>Brief</option>
<option>Detailed</option>
</select>
</div>
</div>
`;
const historyTemplate = `
<div class="history-view">
<h3>Recent Conversations</h3>
<div class="history-item">
<p>Conversation from 2 hours ago</p>
</div>
<div class="history-item">
<p>Conversation from yesterday</p>
</div>
</div>
`;
const handlePromptRequest = (args: PromptRequestEventArgs) => {
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response to: ' + args.prompt);
}, 1000);
};
return (
<div style={{ height: '100vh' }}>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
activeView={0}
>
<ViewsDirective>
<ViewDirective
type='Assist'
name='Chat'
iconCss='e-assistview-icon'
/>
<ViewDirective
type='Custom'
name='Settings'
iconCss='e-icons e-settings'
viewTemplate={settingsTemplate}
/>
<ViewDirective
type='Custom'
name='History'
iconCss='e-icons e-history'
viewTemplate={historyTemplate}
/>
</ViewsDirective>
</AIAssistViewComponent>
</div>
);
}
export default App;Use Cases
Chat + Settings + History
Combine conversation, user settings, and history view:
- Main chat for AI interaction
- Settings for customization
- History for accessing past conversations
Chat + Documentation
Display chat alongside inline documentation:
- Left side: AI chat
- Right side: Help/docs
Chat + Analytics
Show conversation analytics in separate view:
- Main chat area
- Analytics panel showing usage stats
Multi-Language Support
Switch between language-specific views:
- English chat view
- Spanish chat view
- French chat view
Best Practices
Keep views focused: Each view should have clear purpose Use meaningful names: Labels should describe view content Consistent iconography: Use recognizable icons Organize logically: Group related views together Provide defaults: Set sensible activeView on load Performance: Minimize view content for smooth switching
Events and Interactions
Table of Contents
- Component Lifecycle Events
- Prompt Request Event
- Prompt Changed Event
- Event Data Structures
- Custom Event Workflows
- AI Service Integration via Events
Component Lifecycle Events
Created Event
The created event triggers when the AI AssistView component finishes rendering:
import { AIAssistViewComponent } from '@syncfusion/ej2-react-interactive-chat';
import React from 'react';
function App() {
const handleCreated = () => {
console.log('Component initialized and ready to use');
// Initialize other features, load data, etc.
};
return (
<AIAssistViewComponent
id="aiAssistView"
created={handleCreated}
/>
);
}
export default App;Use Cases for Created Event
const handleCreated = () => {
// Load saved conversations
const saved = localStorage.getItem('conversation');
if (saved) {
assistInstance.current.prompts = JSON.parse(saved);
}
// Initialize third-party libraries
// Load user preferences
// Set up event listeners
// Track component creation for analytics
};Prompt Request Event
Overview
The promptRequest event fires when a user submits a prompt. This is the primary event for handling user input:
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = (args: PromptRequestEventArgs) => {
console.log('User prompt:', args.prompt);
console.log('Event args:', args);
// Process the prompt
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response');
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Event Data (PromptRequestEventArgs)
The PromptRequestEventArgs interface provides comprehensive information about the prompt submission:
interface PromptRequestEventArgs {
attachedFiles: FileInfo[]; // Files attached with the prompt
cancel: boolean; // Set to true to cancel the prompt
name: string; // Event name ('promptRequest')
prompt: string; // The user's input text
promptSuggestions: string[]; // Current prompt suggestions
responseToolbarItems: ToolbarItemModel[]; // Toolbar items for response
}Accessing All Event Properties
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// User's prompt text
console.log('Prompt:', args.prompt);
// Attached files (if any)
console.log('Files:', args.attachedFiles);
if (args.attachedFiles && args.attachedFiles.length > 0) {
args.attachedFiles.forEach(file => {
console.log(`- ${file.name} (${file.size} bytes)`);
});
}
// Event name
console.log('Event name:', args.name); // 'promptRequest'
// Current suggestions
console.log('Suggestions:', args.promptSuggestions);
// Response toolbar items
console.log('Response toolbar:', args.responseToolbarItems);
};Canceling Prompt Submission
Use the cancel property to prevent prompt processing:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Validate prompt
if (!args.prompt || args.prompt.trim().length === 0) {
args.cancel = true;
alert('Please enter a prompt');
return;
}
if (args.prompt.length < 3) {
args.cancel = true;
alert('Prompt is too short');
return;
}
if (args.prompt.length > 1000) {
args.cancel = true;
alert('Prompt is too long (max 1000 characters)');
return;
}
// Check for inappropriate content
const bannedWords = ['spam', 'abuse'];
if (bannedWords.some(word => args.prompt.toLowerCase().includes(word))) {
args.cancel = true;
alert('Prompt contains inappropriate content');
return;
}
// If validation passes, process normally
processPrompt(args.prompt);
};Modifying Prompt Suggestions Dynamically
Update suggestions based on the prompt:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
const prompt = args.prompt.toLowerCase();
// Modify suggestions based on prompt content
if (prompt.includes('code')) {
args.promptSuggestions = [
'Show me code examples',
'Explain this code',
'Debug this code'
];
} else if (prompt.includes('help')) {
args.promptSuggestions = [
'How do I get started?',
'Show documentation',
'Contact support'
];
}
// Process the prompt
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response to: ' + args.prompt);
}, 1000);
};Customizing Response Toolbar Dynamically
Modify toolbar items for the response based on prompt content:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Default toolbar items
const defaultItems = [
{ iconCss: 'e-icons e-assist-copy', tooltip: 'Copy' },
{ iconCss: 'e-icons e-assist-like', tooltip: 'Like' },
{ iconCss: 'e-icons e-assist-dislike', tooltip: 'Dislike' }
];
// Add code-specific tools if prompt is about code
if (args.prompt.toLowerCase().includes('code')) {
args.responseToolbarItems = [
...defaultItems,
{ iconCss: 'e-icons e-download', tooltip: 'Download Code' },
{ iconCss: 'e-icons e-play', tooltip: 'Run Code' }
];
} else {
args.responseToolbarItems = defaultItems;
}
// Process prompt
processPrompt(args.prompt);
};Working with Attached Files
Access and validate attached files:
import { AIAssistViewComponent, PromptRequestEventArgs, FileInfo } from '@syncfusion/ej2-react-interactive-chat';
const handlePromptRequest = (args: PromptRequestEventArgs) => {
const files: FileInfo[] = args.attachedFiles || [];
if (files.length === 0) {
// No files attached
processTextOnlyPrompt(args.prompt);
return;
}
// Validate file types
const allowedTypes = ['image/png', 'image/jpeg', 'application/pdf'];
const invalidFiles = files.filter(f => !allowedTypes.includes(f.type));
if (invalidFiles.length > 0) {
args.cancel = true;
alert(`Invalid file types: ${invalidFiles.map(f => f.name).join(', ')}`);
return;
}
// Validate file sizes
const maxSize = 5 * 1024 * 1024; // 5 MB
const oversizedFiles = files.filter(f => f.size > maxSize);
if (oversizedFiles.length > 0) {
args.cancel = true;
alert(`Files too large: ${oversizedFiles.map(f => f.name).join(', ')}`);
return;
}
// Process prompt with files
processPromptWithFiles(args.prompt, files);
};Complete Example with All Properties
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptRequest = (args: PromptRequestEventArgs) => {
console.log('=== Prompt Request Event ===');
console.log('Event name:', args.name);
console.log('Prompt text:', args.prompt);
console.log('Files attached:', args.attachedFiles?.length || 0);
console.log('Current suggestions:', args.promptSuggestions);
console.log('Response toolbar items:', args.responseToolbarItems?.length || 0);
// Validation
if (args.prompt.length > 1000) {
args.cancel = true;
assistInstance.current?.addPromptResponse('⚠️ Prompt too long');
return;
}
// Check for files
if (args.attachedFiles && args.attachedFiles.length > 0) {
const fileNames = args.attachedFiles.map(f => f.name).join(', ');
console.log('Processing with files:', fileNames);
}
// Modify suggestions for next interaction
if (args.prompt.toLowerCase().includes('help')) {
args.promptSuggestions = [
'Documentation',
'Examples',
'Support'
];
}
// Customize response toolbar
args.responseToolbarItems = [
{ iconCss: 'e-icons e-assist-copy', tooltip: 'Copy' },
{ iconCss: 'e-icons e-refresh', tooltip: 'Regenerate' }
];
// Process prompt
setTimeout(() => {
assistInstance.current?.addPromptResponse('Response to: ' + args.prompt);
}, 1000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
enableAttachments={true}
/>
);
}
export default App;Practical Examples
Handle Different Prompt Types:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
const prompt = args.prompt.toLowerCase();
let response = '';
if (prompt.includes('hello')) {
response = 'Hello! How can I help you?';
} else if (prompt.includes('help')) {
response = 'I can assist with various tasks. What do you need?';
} else if (prompt.includes('bye')) {
response = 'Goodbye! Have a great day!';
} else {
response = 'I received your prompt: ' + args.prompt;
}
assistInstance.current?.addPromptResponse(response);
};Validate Before Processing:
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Validate prompt
if (!args.prompt || args.prompt.trim().length === 0) {
assistInstance.current?.addPromptResponse('Please enter a prompt');
return;
}
if (args.prompt.length > 1000) {
assistInstance.current?.addPromptResponse('Prompt is too long');
return;
}
// Safe to process
processPrompt(args.prompt);
};Prompt Changed Event
Overview
The promptChanged event fires whenever the prompt text is modified (as user types). It provides detailed information about the change through PromptChangedEventArgs.
Type: EmitType<PromptChangedEventArgs>
import { AIAssistViewComponent, PromptChangedEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const handlePromptChanged = (args: PromptChangedEventArgs) => {
console.log('Current value:', args.value);
console.log('Previous value:', args.previousValue);
console.log('Text area element:', args.element);
console.log('DOM event:', args.event);
console.log('Event name:', args.name);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptChanged={handlePromptChanged}
/>
);
}
export default App;PromptChangedEventArgs Properties
The event arguments provide comprehensive information about the change:
interface PromptChangedEventArgs {
element: HTMLElement; // The HTML element of the text area container
event: Event; // The underlying DOM event that triggered the change
name: string; // Event name ('promptChanged')
previousValue: string; // The prompt text before the change
value: string; // The current prompt text after the change
}Accessing Event Properties
const handlePromptChanged = (args: PromptChangedEventArgs) => {
// Current text
const currentText = args.value;
console.log('Current:', currentText);
// Previous text
const previousText = args.previousValue;
console.log('Previous:', previousText);
// Calculate what changed
const added = currentText.length - previousText.length;
console.log(`Characters ${added > 0 ? 'added' : 'removed'}:`, Math.abs(added));
// Access the DOM element
const textArea = args.element;
console.log('Element:', textArea);
// Access the original event
const domEvent = args.event;
console.log('Event type:', domEvent.type);
};Use Cases
Real-time Character Count:
import { AIAssistViewComponent, PromptChangedEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useState } from 'react';
function App() {
const [charCount, setCharCount] = useState(0);
const [wordCount, setWordCount] = useState(0);
const handlePromptChanged = (args: PromptChangedEventArgs) => {
const text = args.value;
setCharCount(text.length);
setWordCount(text.trim().split(/\s+/).filter(Boolean).length);
};
return (
<div>
<div className="stats-bar">
<span>Characters: {charCount}/1000</span>
<span>Words: {wordCount}</span>
</div>
<AIAssistViewComponent
id="aiAssistView"
promptChanged={handlePromptChanged}
/>
</div>
);
}Detect Specific Keywords:
const handlePromptChanged = (args: PromptChangedEventArgs) => {
const text = args.value.toLowerCase();
const previousText = args.previousValue.toLowerCase();
// Check if user typed a command
if (text.startsWith('/') && !previousText.startsWith('/')) {
console.log('Command mode activated');
showCommandSuggestions();
}
// Detect @mentions
const mentions = text.match(/@\w+/g);
if (mentions) {
console.log('Mentions detected:', mentions);
showMentionSuggestions(mentions);
}
};Auto-Save Draft:
import { AIAssistViewComponent, PromptChangedEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef } from 'react';
function App() {
const draftTimeoutRef = useRef<NodeJS.Timeout>();
const handlePromptChanged = (args: PromptChangedEventArgs) => {
// Clear previous timeout
if (draftTimeoutRef.current) {
clearTimeout(draftTimeoutRef.current);
}
// Save draft after 2 seconds of no typing
draftTimeoutRef.current = setTimeout(() => {
localStorage.setItem('promptDraft', args.value);
console.log('Draft saved:', args.value);
}, 2000);
};
return (
<AIAssistViewComponent
id="aiAssistView"
promptChanged={handlePromptChanged}
/>
);
}Validate Input in Real-Time:
import React, { useState } from 'react';
function App() {
const [validationMessage, setValidationMessage] = useState('');
const handlePromptChanged = (args: PromptChangedEventArgs) => {
const text = args.value;
// Validation rules
if (text.length > 1000) {
setValidationMessage('⚠️ Prompt is too long (max 1000 characters)');
} else if (text.length > 0 && text.length < 3) {
setValidationMessage('⚠️ Prompt is too short (min 3 characters)');
} else if (text.includes('<script>')) {
setValidationMessage('⚠️ Invalid characters detected');
} else {
setValidationMessage('');
}
};
return (
<div>
{validationMessage && (
<div className="validation-message">{validationMessage}</div>
)}
<AIAssistViewComponent
id="aiAssistView"
promptChanged={handlePromptChanged}
/>
</div>
);
}Track Typing Speed:
function App() {
const lastChangeTimeRef = useRef<number>(Date.now());
const [typingSpeed, setTypingSpeed] = useState(0);
const handlePromptChanged = (args: PromptChangedEventArgs) => {
const now = Date.now();
const timeDiff = now - lastChangeTimeRef.current;
if (timeDiff > 0) {
const charsAdded = Math.abs(args.value.length - args.previousValue.length);
const speed = (charsAdded / timeDiff) * 1000 * 60; // chars per minute
setTypingSpeed(Math.round(speed));
}
lastChangeTimeRef.current = now;
};
return (
<div>
<div>Typing speed: {typingSpeed} CPM</div>
<AIAssistViewComponent
id="aiAssistView"
promptChanged={handlePromptChanged}
/>
</div>
);
}Compare Previous and Current:
const handlePromptChanged = (args: PromptChangedEventArgs) => {
const current = args.value;
const previous = args.previousValue;
// Detect what changed
if (current.length > previous.length) {
const added = current.slice(previous.length);
console.log('Added:', added);
} else if (current.length < previous.length) {
console.log('Characters removed:', previous.length - current.length);
}
// Detect specific actions
if (previous && !current) {
console.log('Text cleared');
}
if (!previous && current) {
console.log('Started typing');
}
};Event Data Structures
PromptRequestEventArgs Interface
interface PromptRequestEventArgs {
prompt: string; // User's prompt text
isInteraction?: boolean; // User-triggered vs programmatic
[key: string]: any; // Other properties
}Working with Event Arguments
const handlePromptRequest = (args: PromptRequestEventArgs) => {
// Access prompt text
const userInput = args.prompt;
// Check if it's a user interaction
const isUserTriggered = args.isInteraction !== false;
// Access additional properties if available
Object.keys(args).forEach(key => {
console.log(`${key}: ${args[key]}`);
});
};Custom Event Workflows
Multi-Step Workflow
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
// Step 1: Validate
if (!validatePrompt(args.prompt)) {
assistInstance.current?.addPromptResponse('Invalid prompt');
return;
}
// Step 2: Sanitize
const cleanPrompt = sanitizeInput(args.prompt);
// Step 3: Process
const result = await processWithAI(cleanPrompt);
// Step 4: Format response
const formattedResponse = formatResponse(result);
// Step 5: Display
assistInstance.current?.addPromptResponse(formattedResponse);
// Step 6: Log for analytics
logInteraction(args.prompt, formattedResponse);
} catch (error) {
console.error('Error processing prompt:', error);
assistInstance.current?.addPromptResponse('An error occurred. Please try again.');
}
};Conditional Workflow Based on Prompt Type
const handlePromptRequest = (args: PromptRequestEventArgs) => {
const prompt = args.prompt;
if (prompt.startsWith('/')) {
// Command handling
handleCommand(prompt);
} else if (prompt.includes('@')) {
// Mention handling
handleMention(prompt);
} else if (prompt.includes('?')) {
// Question handling
handleQuestion(prompt);
} else {
// Regular prompt
handleRegularPrompt(prompt);
}
};AI Service Integration via Events
Basic AI Integration
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
// Show loading state
assistInstance.current?.addPromptResponse('Processing...');
// Call AI service
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: args.prompt }],
temperature: 0.7
})
});
const data = await response.json();
const aiResponse = data.choices[0].message.content;
// Display response
assistInstance.current?.addPromptResponse(aiResponse);
} catch (error) {
assistInstance.current?.addPromptResponse('Error: ' + error.message);
}
};Streaming Response from AI
import { marked } from 'marked';
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: args.prompt }],
stream: true
})
});
const reader = response.body.getReader();
let fullResponse = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = new TextDecoder().decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6));
const content = data.choices[0].delta.content;
if (content) {
fullResponse += content;
// Update UI with partial response
const htmlResponse = marked.parse(fullResponse);
assistInstance.current?.addPromptResponse(htmlResponse);
}
} catch (e) {
// Ignore parse errors
}
}
}
}
} catch (error) {
assistInstance.current?.addPromptResponse('Error: ' + error.message);
}
};Error Handling in Events
const handlePromptRequest = (args: PromptRequestEventArgs) => {
try {
// Validate input
if (!args.prompt?.trim()) {
throw new Error('Prompt cannot be empty');
}
// Process prompt
processPrompt(args.prompt);
} catch (error: any) {
// Show user-friendly error
const errorMessage = error.message || 'An unexpected error occurred';
assistInstance.current?.addPromptResponse(
`<div class="error-message">${errorMessage}</div>`
);
// Log error for debugging
console.error('Prompt handling error:', error);
}
};Stop Responding Event
stopRespondingClick Event
The stopRespondingClick event triggers when users click the "Stop Responding" button during an active prompt request. This is essential for canceling long-running AI operations.
Type: EmitType<StopRespondingEventArgs>
import { AIAssistViewComponent, PromptRequestEventArgs, StopRespondingEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef, useState } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const [isProcessing, setIsProcessing] = useState(false);
const abortControllerRef = useRef<AbortController | null>(null);
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
setIsProcessing(true);
// Create abort controller for cancellation
abortControllerRef.current = new AbortController();
try {
const response = await fetch('https://api.example.com/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: args.prompt }),
signal: abortControllerRef.current.signal // Pass abort signal
});
const data = await response.json();
assistInstance.current?.addPromptResponse(data.response);
} catch (error: any) {
if (error.name === 'AbortError') {
assistInstance.current?.addPromptResponse(
'<div class="cancelled-message">⚠️ Response cancelled by user</div>'
);
} else {
assistInstance.current?.addPromptResponse('Error: ' + error.message);
}
} finally {
setIsProcessing(false);
abortControllerRef.current = null;
}
};
const handleStopResponding = (args: StopRespondingEventArgs) => {
console.log('Stop responding clicked');
console.log('Prompt being cancelled:', args.prompt);
console.log('Data index:', args.dataIndex);
// Cancel the ongoing request
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
setIsProcessing(false);
};
return (
<div>
<div className="status">
{isProcessing && <span>⏳ Processing...</span>}
</div>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
stopRespondingClick={handleStopResponding}
/>
</div>
);
}
export default App;StopRespondingEventArgs Properties
The event arguments provide context about the cancelled operation:
interface StopRespondingEventArgs {
dataIndex: number; // Index of the prompt in the prompts array
event: Event; // Original DOM event
name: string; // Event name ('stopRespondingClick')
prompt: string; // The prompt text that was being processed
}Accessing Event Properties
const handleStopResponding = (args: StopRespondingEventArgs) => {
// Get the prompt being cancelled
const cancelledPrompt = args.prompt;
console.log('Cancelling prompt:', cancelledPrompt);
// Get the position in conversation
const promptIndex = args.dataIndex;
console.log('Prompt index:', promptIndex);
// Access the original DOM event if needed
const domEvent = args.event;
console.log('Event type:', domEvent.type);
// Event name
console.log('Event name:', args.name); // 'stopRespondingClick'
};Streaming Response Cancellation
Cancel streaming responses character-by-character:
import { AIAssistViewComponent, PromptRequestEventArgs, StopRespondingEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import { marked } from 'marked';
import React, { useRef, useState } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const [isStreaming, setIsStreaming] = useState(false);
const streamAbortRef = useRef<AbortController | null>(null);
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
setIsStreaming(true);
streamAbortRef.current = new AbortController();
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: args.prompt }],
stream: true
}),
signal: streamAbortRef.current.signal
});
const reader = response.body?.getReader();
let fullResponse = '';
while (reader && !streamAbortRef.current.signal.aborted) {
const { done, value } = await reader.read();
if (done) break;
const chunk = new TextDecoder().decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ') && !streamAbortRef.current.signal.aborted) {
try {
const data = JSON.parse(line.slice(6));
const content = data.choices[0].delta?.content;
if (content) {
fullResponse += content;
const htmlResponse = marked.parse(fullResponse);
assistInstance.current?.addPromptResponse(htmlResponse);
}
} catch (e) {
// Ignore parse errors
}
}
}
}
} catch (error: any) {
if (error.name === 'AbortError') {
console.log('Streaming cancelled');
}
} finally {
setIsStreaming(false);
streamAbortRef.current = null;
}
};
const handleStopResponding = (args: StopRespondingEventArgs) => {
console.log('Stopping stream for:', args.prompt);
if (streamAbortRef.current) {
streamAbortRef.current.abort();
}
setIsStreaming(false);
// Add cancellation message
assistInstance.current?.addPromptResponse(
'<div class="info-message">🛑 Response generation stopped</div>'
);
};
return (
<div>
<div className="streaming-indicator">
{isStreaming && <span className="pulse">● Generating response...</span>}
</div>
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
stopRespondingClick={handleStopResponding}
/>
</div>
);
}
export default App;Cleanup on Stop
Perform cleanup operations when user cancels:
const handleStopResponding = (args: StopRespondingEventArgs) => {
// Abort API request
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
// Clear any pending timers
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
// Reset loading states
setIsProcessing(false);
setProgress(0);
// Log cancellation for analytics
logEvent('response_cancelled', {
prompt: args.prompt,
index: args.dataIndex,
timestamp: new Date().toISOString()
});
// Notify user
showNotification('Response generation cancelled');
};With Progress Tracking
Track progress and cancel at any point:
import React, { useRef, useState } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const [progress, setProgress] = useState(0);
const shouldContinueRef = useRef(true);
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
shouldContinueRef.current = true;
setProgress(0);
// Simulate long operation
for (let i = 0; i <= 100 && shouldContinueRef.current; i += 10) {
setProgress(i);
await new Promise(resolve => setTimeout(resolve, 500));
}
if (shouldContinueRef.current) {
assistInstance.current?.addPromptResponse('Processing complete!');
setProgress(0);
}
};
const handleStopResponding = (args: StopRespondingEventArgs) => {
shouldContinueRef.current = false;
setProgress(0);
assistInstance.current?.addPromptResponse(
`<div>Cancelled at ${progress}% progress</div>`
);
};
return (
<div>
{progress > 0 && (
<div className="progress-bar">
<div className="progress-fill" style={{ width: `${progress}%` }}>
{progress}%
</div>
</div>
)}
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
stopRespondingClick={handleStopResponding}
/>
</div>
);
}Multiple Request Management
Handle cancellation when multiple requests are in flight:
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const activeRequestsRef = useRef<Map<number, AbortController>>(new Map());
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
const requestId = Date.now();
const abortController = new AbortController();
// Track this request
activeRequestsRef.current.set(requestId, abortController);
try {
const response = await fetch('https://api.example.com/chat', {
method: 'POST',
body: JSON.stringify({ prompt: args.prompt }),
signal: abortController.signal
});
const data = await response.json();
assistInstance.current?.addPromptResponse(data.response);
} catch (error: any) {
if (error.name !== 'AbortError') {
console.error('Request error:', error);
}
} finally {
// Remove from active requests
activeRequestsRef.current.delete(requestId);
}
};
const handleStopResponding = (args: StopRespondingEventArgs) => {
// Cancel all active requests
activeRequestsRef.current.forEach((controller, requestId) => {
controller.abort();
console.log(`Cancelled request ${requestId}`);
});
// Clear the map
activeRequestsRef.current.clear();
assistInstance.current?.addPromptResponse(
'<div>All pending requests cancelled</div>'
);
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
promptRequest={handlePromptRequest}
stopRespondingClick={handleStopResponding}
/>
);
}Best Practices for Stop Responding
✅ Always implement AbortController for fetch requests ✅ Clear all timers and intervals when stopping ✅ Update UI state to reflect cancellation ✅ Provide user feedback about cancellation ✅ Log cancellation events for debugging and analytics ✅ Clean up resources (streams, connections, etc.) ✅ Handle partial responses gracefully ✅ Test cancellation scenarios thoroughly
Complete Event Integration Example
import { AIAssistViewComponent, PromptRequestEventArgs } from '@syncfusion/ej2-react-interactive-chat';
import React, { useRef, useState } from 'react';
function App() {
const assistInstance = useRef<AIAssistViewComponent>(null);
const [isProcessing, setIsProcessing] = useState(false);
const handleCreated = () => {
console.log('Component ready');
loadSavedConversation();
};
const handlePromptChanged = () => {
// Update UI based on prompt changes
const currentPrompt = assistInstance.current?.prompt || '';
console.log('Current text:', currentPrompt);
};
const handlePromptRequest = async (args: PromptRequestEventArgs) => {
if (isProcessing) return;
setIsProcessing(true);
try {
const response = await processUserPrompt(args.prompt);
assistInstance.current?.addPromptResponse(response);
} catch (error) {
assistInstance.current?.addPromptResponse('Error processing request');
} finally {
setIsProcessing(false);
}
};
const loadSavedConversation = () => {
const saved = localStorage.getItem('conversation');
if (saved) {
assistInstance.current.prompts = JSON.parse(saved);
}
};
const processUserPrompt = async (prompt: string): Promise<string> => {
// Implement your logic here
return 'Response to: ' + prompt;
};
return (
<AIAssistViewComponent
id="aiAssistView"
ref={assistInstance}
created={handleCreated}
promptChanged={handlePromptChanged}
promptRequest={handlePromptRequest}
/>
);
}
export default App;Best Practices
Always validate prompts: Check for empty, null, or malicious input Handle errors gracefully: Provide user-friendly error messages Use async/await: For AI service calls and async operations Optimize performance: Debounce rapid event triggers if needed Log interactions: Track prompts and responses for debugging Implement proper state management: For complex workflows
Related skills
How it compares
Pick syncfusion-react-ai-assistview over syncfusion-react-chat-ui when the UI is a generative AI prompt assistant rather than a human-to-human chat widget.
FAQ
Which package does syncfusion-react-ai-assistview use?
syncfusion-react-ai-assistview uses AIAssistViewComponent from @syncfusion/ej2-react-interactive-chat, wiring promptRequest callbacks to connect generative AI services and display responses in a structured assistant UI.
What does syncfusion-react-ai-assistview help developers build?
syncfusion-react-ai-assistview helps developers build React AI assistant interfaces with prompt input, toolbar commands, prompt suggestions, streaming AI responses, and conversation history via the prompts collection.