This tutorial shows you how to add an AI agent to your React application.
Not a chatbot that answers questions. An agent that understands your app's state and can take action—create records, update data, trigger workflows.
By the end, you'll know how to:
- Install the component
- Add it to your app with a display mode
- Give the agent context about your app's state
- Define tools the agent can call
You can apply these patterns to any React app—whether you're building a dashboard, a CRM, an admin panel, or something else entirely.
Step 1: Install
npm install @inappai/react
Step 2: Add the Component
Drop <InAppAI> into your app. It handles the chat interface and communication with your agent.
import { useState } from 'react';
import { InAppAI, Message } from '@inappai/react';
function App() {
const [messages, setMessages] = useState<Message[]>([]);
return (
<div>
{/* Your existing app UI */}
<InAppAI
agentId="your-agent-id"
messages={messages}
onMessagesChange={setMessages}
displayMode="popup"
/>
</div>
);
}
Display Modes
Choose how the agent appears in your app:
| Mode | Description |
|---|---|
popup |
Floating button that opens a chat window |
sidebar |
Fixed panel on the side of your app |
inline |
Embedded directly in your layout |
fullscreen |
Takes over the entire viewport |
modal |
Centered overlay |
hidden |
No UI—control programmatically |
<InAppAI displayMode="sidebar" />
Pick the one that fits your UX. Most apps start with popup or sidebar.
Step 3: Provide Context
Context tells the agent what's happening in your app right now. Without it, the agent is blind.
<InAppAI
agentId="your-agent-id"
messages={messages}
onMessagesChange={setMessages}
context={() => ({
currentUser: { name: 'Alice', role: 'admin' },
currentPage: 'dashboard',
selectedItems: selectedItems,
})}
displayMode="popup"
/>
Why a function? The agent needs fresh data after each action. By passing a function, InAppAI calls it again after every tool execution to get the latest state.
What to include in context
Include whatever helps the agent understand your app:
- Current user — name, role, permissions
- Current view — which page, what filters are active
- Selected items — what the user has focused on
- Relevant data — records, counts, status
Keep it concise. Only include what the agent needs to help the user.
Step 4: Define Tools
A tool is a function the agent can call. This is how the agent takes action in your app.
Every tool has four parts:
{
name: 'toolName', // What the agent calls it
description: '...', // When to use it
parameters: { ... }, // What inputs it needs
handler: async () => { ... } // What it actually does
}
Here's a simple example—a tool that searches for something:
const tools = [
{
name: 'search',
description: 'Search for items by keyword',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search term' },
},
required: ['query'],
},
handler: async ({ query }) => {
const results = items.filter(item =>
item.name.toLowerCase().includes(query.toLowerCase())
);
return { results, count: results.length };
},
},
];
Pass your tools to the component:
<InAppAI
agentId="your-agent-id"
messages={messages}
onMessagesChange={setMessages}
tools={tools}
context={() => ({ items })}
displayMode="popup"
/>
How tool execution works
When a user says "Search for budget reports":
- Agent reads the description → decides
searchis the right tool - Agent extracts parameters →
{ query: "budget reports" } - Handler runs → filters your data
- Agent sees the result → responds "Found 3 items matching 'budget reports'."
Tools can modify state
Tools aren't just for reading data. They can create, update, and delete:
{
name: 'createItem',
description: 'Create a new item',
parameters: {
type: 'object',
properties: {
name: { type: 'string', description: 'Item name' },
category: { type: 'string', enum: ['A', 'B', 'C'] },
},
required: ['name'],
},
handler: async ({ name, category = 'A' }) => {
const newItem = { id: crypto.randomUUID(), name, category };
setItems(prev => [...prev, newItem]);
return { success: true, item: newItem };
},
}
After the handler runs and updates state, InAppAI calls your context() function again. The agent sees the updated data and can respond accordingly.
Putting It Together: A Task Manager Example
Let's see how these pieces combine in a real application. Here's a task manager where the AI agent can create, list, complete, and delete tasks.
Try it live: react-demo.inappai.com
import { useState } from 'react';
import { InAppAI, Tool, Message } from '@inappai/react';
interface Task {
id: string;
text: string;
priority: 'low' | 'medium' | 'high';
completed: boolean;
}
export function TaskManager() {
const [tasks, setTasks] = useState<Task[]>([]);
const [messages, setMessages] = useState<Message[]>([]);
const tools: Tool[] = [
{
name: 'createTask',
description: 'Create a new task when the user wants to add something to their list',
parameters: {
type: 'object',
properties: {
text: { type: 'string', description: 'The task description' },
priority: {
type: 'string',
enum: ['low', 'medium', 'high'],
description: 'Priority level. Default to medium if not specified.',
},
},
required: ['text'],
},
handler: async ({ text, priority = 'medium' }) => {
const newTask: Task = { id: crypto.randomUUID(), text, priority, completed: false };
setTasks(prev => [...prev, newTask]);
return { success: true, task: newTask };
},
},
{
name: 'listTasks',
description: 'Get tasks, optionally filtered by status or priority',
parameters: {
type: 'object',
properties: {
status: { type: 'string', enum: ['all', 'active', 'completed'] },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
},
},
handler: async ({ status = 'all', priority }) => {
let filtered = tasks;
if (status === 'active') filtered = tasks.filter(t => !t.completed);
if (status === 'completed') filtered = tasks.filter(t => t.completed);
if (priority) filtered = filtered.filter(t => t.priority === priority);
return { tasks: filtered, count: filtered.length };
},
},
{
name: 'completeTask',
description: 'Mark a task as completed by ID or matching text',
parameters: {
type: 'object',
properties: {
identifier: { type: 'string', description: 'Task ID or keyword from task text' },
},
required: ['identifier'],
},
handler: async ({ identifier }) => {
const task = tasks.find(
t => t.id === identifier || t.text.toLowerCase().includes(identifier.toLowerCase())
);
if (!task) return { success: false, error: 'Task not found' };
setTasks(prev => prev.map(t => t.id === task.id ? { ...t, completed: true } : t));
return { success: true, completed: task.text };
},
},
{
name: 'deleteTask',
description: 'Remove a task permanently',
parameters: {
type: 'object',
properties: {
identifier: { type: 'string', description: 'Task ID or keyword from task text' },
},
required: ['identifier'],
},
handler: async ({ identifier }) => {
const task = tasks.find(
t => t.id === identifier || t.text.toLowerCase().includes(identifier.toLowerCase())
);
if (!task) return { success: false, error: 'Task not found' };
setTasks(prev => prev.filter(t => t.id !== task.id));
return { success: true, deleted: task.text };
},
},
];
return (
<div style={{ padding: 20 }}>
<h1>My Tasks</h1>
<ul>
{tasks.map(task => (
<li key={task.id} style={{ opacity: task.completed ? 0.5 : 1 }}>
[{task.priority}] {task.text} {task.completed && '✓'}
</li>
))}
</ul>
{tasks.length === 0 && <p>No tasks yet. Ask the agent to add one.</p>}
<InAppAI
agentId="your-agent-id"
messages={messages}
onMessagesChange={setMessages}
tools={tools}
context={() => ({
tasks: tasks.map(({ id, text, priority, completed }) => ({ id, text, priority, completed })),
stats: { total: tasks.length, active: tasks.filter(t => !t.completed).length },
})}
displayMode="popup"
theme="light"
/>
</div>
);
}
What you can say to the agent
| You say | Agent does |
|---|---|
| "Add a task to review the Q1 budget" | Calls createTask
|
| "Add a high-priority task to call John" | Calls createTask with priority: "high"
|
| "What tasks do I have?" | Calls listTasks
|
| "Show me high-priority items" | Calls listTasks with priority filter |
| "Mark the budget task as done" | Calls completeTask
|
| "Delete the completed tasks" | Calls deleteTask
|
The agent understands natural language, extracts the right parameters, and executes your tools.
Beyond Client-Side: Knowledge Base and Backend
Everything so far runs in the browser. But production apps often need more:
Knowledge Base (RAG)
Want the agent to answer questions from your documentation, help articles, or product guides? InAppAI supports Retrieval Augmented Generation out of the box.
Add URLs to your knowledge base through the dashboard at app.inappai.com. The system crawls your content, splits it into searchable chunks, and includes relevant sections when the agent responds.
Supported sources:
- Documentation sites (GitBook, ReadTheDocs, Docusaurus)
- Blog posts and help articles
- GitHub READMEs and markdown files
When a user asks a question, the agent searches your knowledge base using semantic similarity—not just keyword matching—and weaves the relevant information into its response.
Backend Configuration
The agentId prop connects your component to InAppAI's managed backend, which handles:
- AI provider routing — OpenAI, Anthropic, or Google, configurable per agent
- Rate limiting — protect against abuse
- Usage tracking — monitor requests and costs
- CORS — restrict which domains can call your agent
For user-specific features, pass an authToken:
<InAppAI
agentId="your-agent-id"
authToken={userJwtToken}
// ... other props
/>
This enables per-user rate limits and lets you identify users in your analytics.
All backend settings are configured through the dashboard—no infrastructure to manage.
Apply This to Your App
The task manager is just one example. You can use these same patterns for:
- CRM: Create contacts, log activities, update deal stages
- Admin dashboard: Filter data, export reports, manage users
- E-commerce: Search products, update inventory, process orders
- Project management: Create tickets, assign tasks, update status
- Support portal: Search knowledge base, create tickets, escalate issues
The key is to think about what actions users commonly take in your app, then expose those as tools.
What's Next
You now have the building blocks to add an AI agent to any React app:
- Display modes — control how the agent appears
- Context — keep the agent aware of your app's state
- Tools — let the agent take action
From here, you can:
- Add more tools — any function can become a tool
- Expand context — include user info, filters, current view
- Customize the UI — 7 themes, custom styling options
Check out the docs for advanced features like knowledge base RAG and multi-provider failover.
Resources
- Live Demo: react-demo.inappai.com
- Docs: inappai.com/docs
- GitHub: github.com/inappai/react
Questions? Drop a comment below.
Top comments (0)