iaadillatif/ai-chatbot
A complete AI Chatbot application built with Next.js 14, React 18, TypeScript 5, LangChain.js, FAISS, and Google Gemini AI using Retrieval-Augmented Generation (RAG). Features rate limiting, session persistence, admin controls, and automatic model fallback.
AI ChatBot - Created by Aadil Latif
A complete AI Chatbot application built with Next.js 14, React 18,
TypeScript 5, LangChain.js, FAISS, and Google Gemini AI using
Retrieval-Augmented Generation (RAG). Features rate limiting, session
persistence, admin controls, and automatic model fallback.
✨ Features
🤖 RAG (Retrieval-Augmented Generation) - Answers grounded in your FAQ
knowledge base
⚡ Fast AI Responses - Gemini AI with 4-model automatic fallback chain
(2.5-flash-lite → 2.5-flash → 3-flash-preview)
🔍 Semantic Search - FAISS for efficient vector similarity matching
💬 Real-time Chat - Interactive chat interface with message history
📱 Responsive Design - Beautiful mobile-friendly UI with Tailwind CSS
🌙 Dark Mode - Built-in theme switching
🔒 Type-Safe - Full TypeScript support
🚀 Rate Limiting - 10 requests per 24 hours per IP with Redis persistence
💾 Session Persistence - Automatic session management with 24-hour TTL
(Redis + localStorage)
🔐 Admin Features - Password-protected session management endpoints
⚙️ Automatic Failover - Model fallback chain for error recovery
📊 Debug Endpoints - Monitor rate limits and model status
📋 Table of Contents
- Getting Started
- Installation
- Configuration
- Project Structure
- How It Works
- Core Features
- API Documentation
- Rate Limiting
- Session Persistence
- Admin Features
- Gemini Model Fallback
- Customization
- Deployment
- Troubleshooting
- Tech Stack
Getting Started
Prerequisites
- Node.js 18+ (tested with 20.17+, 22.9+)
- npm or yarn
- Google API Key with Gemini API enabled
- Redis URL (optional, for production rate limiting) - can use
Upstash
Clone or Setup the Project
# Clone the repo
git clone https://github.com/iaadillatif/ai-chatbot.git
# Navigate to the chatbot directory
cd chatbotQuick 5-Minute Setup
# 1. Install dependencies
npm install
# 2. Create .env.local file with your API keys
GEMINI_API_KEY=your_google_api_key_here
REDIS_URL=optional_redis_url_here
ADMIN_PASSWORD=your_secure_admin_password
# 3. Start development server
npm run dev
# 4. Open browser
http://localhost:3000Installation
Step 1: Install Node Modules
npm installInstalled packages:
next- React framework with API routesreact- UI librarytypescript- Type safetytailwindcss- Stylinglangchain- AI orchestration@google/genai- Gemini APIredis- Redis client for rate limitinglucide-react- Icon library
Step 2: Set Up Environment Variables
Create .env in the project root:
# ============================================
# REQUIRED - Google Gemini API
# ============================================
GEMINI_API_KEY=your_google_api_key_here
# ============================================
# OPTIONAL - Rate Limiting & Session Persistence
# ============================================
# Use for production persistence (if not set, uses in-memory fallback)
REDIS_URL=redis://default:password@your-redis-host:6379
# ============================================
# OPTIONAL - Admin Access
# ============================================
# Required for accessing admin endpoints
ADMIN_PASSWORD=your_secure_admin_password
# ============================================
# OPTIONAL - Application Settings
# ============================================
NEXT_PUBLIC_APP_NAME=AI ChatBot
NEXT_PUBLIC_MAX_MESSAGE_LENGTH=500
LOG_LEVEL=info
NODE_ENV=developmentGet Google API Key
- Visit https://aistudio.google.com/app/api-keys
- Click "Create API key"
- Copy the key
- Paste into
.env.local
Get Redis URL (Optional)
For production, use a managed Redis service:
Option A: Upstash (Recommended)
- Go to https://upstash.com
- Create free Redis database
- Copy connection string:
redis://default:password@host:6379
Option B: Local Redis
# macOS
brew install redis
redis-server
# Docker
docker run -d -p 6379:6379 redis:latest
# Windows (WSL)
docker run -d -p 6379:6379 redis:latestStep 3: Run Development Server
npm run devServer starts at http://localhost:3000
Configuration
Environment Configuration
All configuration is managed through .env. No code changes needed for setup.
Knowledge Base Setup
The chatbot uses RAG (Retrieval-Augmented Generation) to answer questions
based on your FAQ document.
To add/customize FAQs:
- Create or edit a Word document named
CHATBOT.docx - Place it in the
public/folder at the root of your project - Add your FAQs content, documentation, or knowledge base to this document
- Restart the development server
- The chatbot will automatically load and index your document content
📁 File Location: public/CHATBOT.docx
Your Project/
├── public/
│ └── CHATBOT.docx ← Place your FAQ document here
├── app/
├── components/
├── lib/
└── ...
✅ The system will automatically:
- Load the DOCX file on startup
- Extract all text content
- Create embeddings for semantic search
- Answer questions based on your document content
- Cache the document for performance
Customize Chat UI
Edit components/ChatBot.tsx:
// Change header text
<h1 className="text-2xl font-bold">Your Custom Title</h1>;
// Change colors (Tailwind classes)
className = "bg-blue-500"; // User message
className = "bg-green-500"; // Assistant message
// Change icons (lucide-react)
import { MessageCircle, Send, Trash2 } from "lucide-react";Customize AI Behavior
Edit lib/rag.ts:
// Change system prompt
const systemPrompt = `You are a helpful assistant...
Add your custom instructions here.`;
// Change number of retrieved documents
const relevantDocs = await retrieveRelevantDocs(userQuery, 5); // Was 3
// Change model (will use fallback chain regardless)
// Models tried in order: gemini-2.5-flash-lite → gemini-2.5-flash → gemini-3-flash-previewRate Limiting Configuration
Modify in app/api/chat/route.ts:
// Change limit to 20 requests per 1 hour
const rateLimitResult = await checkRateLimit(clientIP, 20, 3600);Project Structure
chatbot/
│
├── 📱 Frontend
│ ├── app/
│ │ ├── api/
│ │ │ ├── chat/
│ │ │ │ └── route.ts ✅ Chat endpoint
│ │ │ ├── sessions/
│ │ │ │ ├── route.ts ✅ List sessions (admin)
│ │ │ │ └── [id]/
│ │ │ │ └── route.ts ✅ Get/delete session (admin)
│ │ │ └── debug/
│ │ │ ├── rate-limit-status/
│ │ │ │ └── route.ts ✅ Debug rate limiter
│ │ │ └── model-status/
│ │ │ └── route.ts ✅ Debug current model
│ │ ├── layout.tsx ✅ Root layout
│ │ ├── page.tsx ✅ Main page
│ │ └── globals.css ✅ Global styles
│ │
│ └── components/
│ └── ChatBot.tsx ✅ Chat UI component
│
├── 📁 Public Files
│ └── public/
│ └── CHATBOT.docx ⭐ Your FAQ/Knowledge Base (REQUIRED)
│
├── 🧠 Backend/AI
│ └── lib/
│ ├── adminAuth.ts ✅ Admin Authentication
│ ├── documentProcessor.ts ✅ DOCX file extraction
│ ├── rag.ts ✅ RAG + Gemini + Fallback
│ └── rateLimiter.ts ✅ Rate limiting
│ └── sessionManager.ts ✅ Managing sessions
│
├── ⚙️ Config
│ ├── package.json ✅ Dependencies
│ ├── tsconfig.json ✅ TypeScript
│ ├── next.config.mjs ✅ Next.js
│ ├── tailwind.config.ts ✅ Tailwind
│ ├── .env.example ✅ Secrets (example)
│
└── 📚 Documentation
└── README.md
How It Works
Chat Flow Diagram
┌──────────────────────────────────────────────────────────┐
│ 1. User Types Question in ChatBot Component │
│ "What is your return policy?" │
└─────────────────┬────────────────────────────────────────┘
│ POST /api/chat
│ Check rate limit (10/24h per IP)
│ Get/create session for IP
▼
┌──────────────────────────────────────────────────────────┐
│ 2. API Route: app/api/chat/route.ts │
│ - Extract client IP │
│ - Check rate limit │
│ - Get or create session │
│ - Call RAG system │
└─────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 3. RAG System: lib/rag.ts │
│ Initialize Vector Store (cached) │
│ - Load FAQ data from CHATBOT.docx │
│ - Convert to embeddings │
│ - Index with FAISS │
└─────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 4. Semantic Search │
│ - Embed user question │
│ - Find 3 most relevant FAQs │
│ - Retrieve matching Q&A pairs │
└─────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 5. Try Gemini Models (Fallback Chain) │
│ Try: gemini-2.5-flash-lite │
│ ├─ Success? Return answer │
│ └─ Failed? Try: gemini-2.5-flash │
│ ├─ Success? Return answer │
│ └─ Failed? Try: gemini-3-flash-preview │
└─────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 6. Response Handling │
│ - Return JSON with answer │
│ - Include rate limit headers │
│ - Update session in Redis + localStorage │
│ - ChatBot displays answer │
└──────────────────────────────────────────────────────────┘
Session & Rate Limit Flow
Example:
First Request from IP 192.168.1.100
├─ Extract IP from request headers
├─ Check Redis for existing session
├─ Session not found → Create new UUID
├─ Save session to Redis (TTL: 24 hours)
├─ Initialize rate limit counter (10)
└─ Decrement to 9, allow request
Browser Refresh (Same IP, Same Session)
├─ Extract IP: 192.168.1.100
├─ Check Redis → Found existing session
├─ Reuse session + conversation history
├─ Check rate limit (9 left)
└─ Decrement to 8, allow request
After 10 Requests
├─ Rate limit counter reaches 0
├─ Next request rejected (429 Too Many Requests)
├─ Response includes Retry-After header
└─ UI shows "Rate Limit Exceeded" with countdown timer
After 24 Hours
├─ Redis TTL expires
├─ Session automatically deleted
├─ Rate limit counter reset
├─ New session created on next request
└─ User can ask 10 more questions
Core Features
1. Rate Limiting (10 requests/24h per IP)
- Automatic IP detection from request headers
- Redis persistence for multi-server deployments
- In-memory fallback if Redis unavailable
- Client-side caching in localStorage
- Progress bar UI showing requests remaining
- Countdown timer to reset
Headers returned:
X-RateLimit-Limit: 10X-RateLimit-Remaining: 7X-RateLimit-Reset: 2026-02-26T21:30:00.000Z
2. Session Persistence (24-hour TTL per IP)
- Automatic - No manual session management needed
- IP-based - Each unique IP gets its own session
- 24-hour expiry - Sessions expire automatically
- Conversation history - Full chat history maintained
- Hybrid storage - Redis (server) + localStorage (client)
- Cross-device - Same IP gets same session after browser refresh
3. Admin Features
- Password-protected session endpoints
- View all sessions - List active sessions with IP and TTL
- View session history - See all messages in a session
- Delete sessions - Clear individual sessions manually
- Server-side verification - Password never sent to frontend
4. Gemini Model Fallback
- 3-model chain - Automatic switching if a model fails
- Transparent - Users never see model switching
- Error recovery - Handles token limits, server errors, timeouts
- Debug endpoint - Check which model is currently active
Fallback order:
gemini-2.5-flash-lite(primary)gemini-2.5-flash(fallback 1)gemini-3-flash-preview(fallback 2)
5. Semantic Search (RAG)
- FAISS indexing for O(log n) lookup time
- Vector embeddings for semantic similarity
- Configurable retrieval - Retrieve 1-5+ relevant FAQs
- Cached vector store - Reused across requests
- No external vector DB - Self-contained, runs locally
API Documentation
Chat Endpoint
POST /api/chat
Send a question to get an AI-powered answer.
Request:
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"message": "What is your return policy?"
}'Response (Success):
{
"success": true,
"message": "What is your return policy?",
"answer": "We offer 30-day returns on all products...",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-25T21:30:00.000Z"
}Response Headers:
HTTP/1.1 200 OK
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 2026-02-26T21:30:00.000Z
Response (Rate Limited):
{
"success": false,
"error": "Rate limit exceeded",
"message": "You have exceeded the limit of 10 requests per 24 hours",
"resetAt": "2026-02-26T15:45:30.000Z"
}Status: 429 Too Many Requests
Admin Sessions Endpoints
All admin endpoints require authentication via X-Admin-Password header or
admin_password query parameter.
List All Active Sessions
GET /api/sessions
curl -H "X-Admin-Password: your_password" \
http://localhost:3000/api/sessionsResponse:
{
"success": true,
"sessions": [
{
"ip": "192.168.1.100",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"timeLeftSeconds": 82800,
"expiresAt": "2026-02-26T10:30:00.000Z"
},
{
"ip": "203.0.113.45",
"sessionId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"timeLeftSeconds": 50400,
"expiresAt": "2026-02-26T00:30:00.000Z"
}
],
"count": 2,
"timestamp": "2026-02-25T21:30:00.000Z"
}Get Session History
GET /api/sessions/{session_id}
curl -H "X-Admin-Password: your_password" \
http://localhost:3000/api/sessions/session-id-1Response:
{
"session_id": "session-id-1",
"messages": [
{
"type": "user",
"content": "Hello",
"timestamp": "2026-02-25T21:30:00.000Z"
},
{
"type": "assistant",
"content": "Hi! How can I help?",
"timestamp": "2026-02-25T21:30:05.000Z"
}
],
"timestamp": "2026-02-25T21:30:10.000Z"
}Delete Session
DELETE /api/sessions/{session_id}
curl -X DELETE \
-H "X-Admin-Password: your_password" \
http://localhost:3000/api/sessions/session-id-1Response:
{
"message": "Session session-id-1 cleared",
"session_id": "session-id-1",
"timestamp": "2026-02-25T21:30:15.000Z"
}Debug Endpoints
Rate Limit Status
GET /api/debug/rate-limit-status
Check Redis connectivity and rate limit data.
curl http://localhost:3000/api/debug/rate-limit-statusResponse:
{
"redis_connected": true,
"rate_limit_keys": 5,
"sample_data": {
"rate-limit:192.168.1.100": "7"
},
"timestamp": "2026-02-25T21:30:00.000Z"
}Model Status
GET /api/debug/model-status
Check which Gemini model is currently active in the fallback chain.
curl http://localhost:3000/api/debug/model-statusResponse:
{
"success": true,
"currentModel": "gemini-2.5-flash-lite",
"availableModels": [
"gemini-2.5-flash-lite",
"gemini-2.5-flash",
"gemini-3-flash-preview"
],
"message": "Currently using gemini-2.5-flash-lite. If this fails, will fallback to gemini-2.5-flash, gemini-3-flash-preview",
"timestamp": "2026-02-25T21:30:00.000Z"
}Rate Limiting
Overview
- Limit: 10 requests per 24 hours
- Scope: Per IP address (extracted from client request)
- Storage: Redis (if available) or in-memory fallback
- Reset: Automatic after 24 hours
How It Works
- IP Extraction - Gets IP from headers (X-Forwarded-For, X-Real-IP,
CF-Connecting-IP) - Limit Check - Verifies request count against 10/24h limit
- Storage - Persists in Redis with 24-hour TTL or in-memory map
- Response - Returns 200 OK or 429 Too Many Requests with Retry-After
Response Headers
| Header | Example | Description |
|---|---|---|
| X-RateLimit-Limit | 10 | Total requests allowed |
| X-RateLimit-Remaining | 7 | Requests left in window |
| X-RateLimit-Reset | 2026-02-26T21:30:00.000Z | When limit resets (ISO 8601) |
| Retry-After | 3600 | Seconds to wait (only when 429) |
Frontend UI Indicator
The ChatBot component shows:
- Green bar - 6+ requests remaining (✓ healthy)
- Yellow bar - 2-5 requests remaining (
⚠️ caution) - Red bar - 0-1 requests remaining (🛑 almost out)
- Gray blocked - 0 requests remaining (❌ rate limited)
- Countdown timer - Shows hours/minutes/seconds until reset
localStorage Persistence
Rate limit data is synced to localStorage:
// Keys used:
localStorage.getItem("chatbot_rate_limit_remaining"); // "7"
localStorage.getItem("chatbot_rate_limit_reset"); // "2026-02-26T21:30:00.000Z"Testing Rate Limiting
# First 10 requests will succeed
for i in {1..10}; do
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Hello?"}'
done
# 11th request will be rate limited
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Hello?"}'
# Returns: 429 Too Many RequestsSession Persistence
Overview
Sessions are automatically persisted to Redis for 24 hours per IP
address. No manual session management needed.
How It Works
- First Request - Server creates unique UUID session
- Persisted - Session ID saved to Redis with 24-hour TTL
- Subsequent Requests - Same IP retrieves existing session
- Conversation History - Full chat maintained across browser refreshes
- Auto-Expire - Sessions automatically expire after 24 hours
Session Lifecycle
| Event | Description | Duration |
|---|---|---|
| Created | When user sends first message from new IP | N/A |
| Persisted | Stored in Redis with TTL | 24 hours |
| Retrieved | Automatically reused for same IP | Per request |
| Timeout | Expires and new session created | 24 hours |
| Admin Delete | Manually cleared by admin | Immediate |
Storage Mechanism
Redis Storage:
Key: session:{IP_ADDRESS}
Value: {session-uuid-string}
TTL: 86400 seconds (24 hours)
Example:
Key: session:192.168.1.100
Value: 550e8400-e29b-41d4-a716-446655440000
Expires: 24 hours from now
localStorage (Client-side Cache):
// Keys synced automatically:
localStorage.setItem(
"chatbot_session_id",
"550e8400-e29b-41d4-a716-446655440000",
);
localStorage.setItem("chatbot_rate_limit_remaining", "7");
localStorage.setItem("chatbot_rate_limit_reset", "2026-02-26T21:30:00.000Z");Benefits
- ✅ Automatic - No manual session management
- ✅ Persistent - Survives browser refresh and close
- ✅ Conversation History - Full chat history maintained
- ✅ IP-Based - Each IP is independent
- ✅ Time-Limited - Automatically expires after 24 hours
- ✅ Hybrid - Redis (production) + localStorage (offline)
Examples
Example 1: First Request
Client IP: 192.168.1.100
Message: "Hello"
Server:
1. Check Redis: "session:192.168.1.100" → null
2. Create new session: "abc123def456"
3. Save to Redis with 24h TTL
4. Process message
5. Return response with session_id
Example 2: Browser Refresh (Same IP)
Client IP: 192.168.1.100 (same as before)
Message: "What's your shipping?"
Server:
1. Check Redis: "session:192.168.1.100" → "abc123def456"
2. Reuse existing session
3. Retrieve full chat history
4. Process new message
5. Return response with same session_id
Result: Same session, conversation history preserved
Example 3: After 24 Hours (Same IP)
Client IP: 192.168.1.100 (24+ hours later)
Message: "Do you have a sale?"
Server:
1. Check Redis: "session:192.168.1.100" → null (expired)
2. Create new session: "xyz789uvw000"
3. Save to Redis with 24h TTL
4. Process message (fresh start)
5. Return response with new session_id
Result: New session, fresh conversation history
Admin Viewing Sessions
Admins can view all active sessions:
curl -H "X-Admin-Password: your_password" \
http://localhost:3000/api/sessions
# Response includes:
{
"sessions": [
{
"ip": "192.168.1.100",
"sessionId": "abc123def456",
"timeLeftSeconds": 82800,
"expiresAt": "2026-02-26T10:30:00.000Z"
}
]
}Troubleshooting
Issue: Sessions not persisting across refresh
- Check Redis connection:
curl http://localhost:3000/api/debug/rate-limit-status - Verify
.env.localhasREDIS_URLset - Check browser localStorage for
chatbot_session_id
Issue: Different sessions on same IP
- May indicate different IPs (proxy/VPN changed)
- Check server logs for
[API] Client IP:output - Verify
X-Forwarded-Forheader is set correctly
Issue: Sessions lost after server restart
- In-memory fallback loses sessions
- Use Redis for production persistence
- Configure
REDIS_URLin.env.local
Admin Features
Setup
Add to .env:
ADMIN_PASSWORD=your_secure_admin_password_hereAuthentication
Provide password in requests via:
Method 1: HTTP Header (Recommended)
curl -H "X-Admin-Password: your_password" \
http://localhost:3000/api/sessionsMethod 2: Query Parameter
curl http://localhost:3000/api/sessions?admin_password=your_passwordAvailable Actions
| Action | Endpoint | Method | Purpose |
|---|---|---|---|
| List Sessions | /api/sessions |
GET | View all active sessions |
| View History | /api/sessions/{id} |
GET | See all messages in a session |
| Delete Session | /api/sessions/{id} |
DELETE | Manually clear a session |
| Rate Limit Status | /api/debug/rate-limit-status |
GET | Check Redis connectivity |
| Model Status | /api/debug/model-status |
GET | Check current Gemini model |
Security Notes
- ✅ Password verified server-side only
- ✅ Never exposed in client-side code
- ✅ Use environment variable for all deployments
⚠️ Use strong password in production⚠️ Use HTTPS in production
Example Admin Frontend
// utils/admin.ts
export async function getAdminSessions(adminPassword: string) {
const response = await fetch("/api/sessions", {
headers: { "X-Admin-Password": adminPassword },
});
if (!response.ok) throw new Error("Unauthorized");
return response.json();
}
export async function deleteSession(sessionId: string, adminPassword: string) {
const response = await fetch(`/api/sessions/${sessionId}`, {
method: "DELETE",
headers: { "X-Admin-Password": adminPassword },
});
if (!response.ok) throw new Error("Unauthorized");
return response.json();
}Gemini Model Fallback
Overview
The system automatically handles Gemini API failures by trying multiple models
in a fallback chain. If one model fails, it automatically tries the next model
without user interruption.
Fallback Chain
Models are tried in this order:
- gemini-2.5-flash-lite (Primary, lightweight)
- gemini-2.5-flash (Standard, balanced)
- gemini-3-flash-preview (Fallback, advanced)
Error Handling
The system handles these types of errors:
✅ Token limit reached ✅ Server errors (5xx) ✅ Rate limits (429) ✅ Network
timeouts ✅ Invalid requests ✅ Any unknown errors
How It Works
User sends message
↓
Try gemini-2.5-flash-lite
├─ Success → Use response
└─ Failure → Log error, try next
↓
Try gemini-2.5-flash
├─ Success → Use response
└─ Failure → Log error, try next
↓
Try gemini-3-flash-preview
├─ Success → Use response
└─ Failure → Log error, try next
Console Logs
When the system switches models, you'll see:
Successful request:
[RAG] Attempting to use model: gemini-2.5-flash-lite
[RAG] Successfully used model: gemini-2.5-flash-lite
Model failure with fallback:
[RAG] Model gemini-2.5-flash-lite failed: 429 Too Many Requests
[RAG] Attempting to use model: gemini-2.5-flash
[RAG] Successfully used model: gemini-2.5-flash
Debug Endpoint
Check which model is currently being used:
curl http://localhost:3000/api/debug/model-statusResponse:
{
"success": true,
"currentModel": "gemini-2.5-flash-lite",
"availableModels": [
"gemini-2.5-flash-lite",
"gemini-2.5-flash",
"gemini-3-flash-preview"
],
"message": "Currently using gemini-2.5-flash-lite. If this fails, will fallback to gemini-2.5-flash, gemini-3-flash-preview",
"timestamp": "2026-02-25T21:30:00.000Z"
}Implementation
Located in lib/rag.ts:
const GEMINI_MODELS = [
"gemini-2.5-flash-lite",
"gemini-2.5-flash",
"gemini-3-flash-preview",
] as const;
async function callGeminiAPI(prompt: string): Promise<string> {
for (const model of GEMINI_MODELS) {
try {
return await callGeminiAPIWithModel(prompt, model);
} catch (error) {
// Log and try next model
continue;
}
}
throw new Error("All Gemini models failed");
}Benefits
✅ Automatic Recovery - No manual intervention ✅ Transparent - Users
see no model switching ✅ No Service Interruption - Always get a response ✅
Efficient - Uses lighter models only when needed ✅ Observable - Console
logs track model usage ✅ Debuggable - Status endpoint shows current model
Customization
Add/Edit FAQs and Knowledge Base
Edit public/CHATBOT.docx:
- Open the
CHATBOT.docxfile in Microsoft Word or compatible editor - Add or edit your FAQ content, product information, documentation, or any
knowledge base content - Save the file
- Restart your development server (
npm run dev) - The chatbot will automatically load the new content
Example Document Structure:
Frequently Asked Questions
Q: What is your return policy?
A: We offer 30-day returns on all products.
Q: Do you ship internationally?
A: Yes, we ship to 50+ countries.
Product Information
...(add your content)
💡 Tips:
- Use clear, well-formatted text for better search results
- Include headers and sections for organization
- The system uses semantic search, so content quality matters
- Longer, more detailed answers provide better context
Customize Chat Colors
Edit components/ChatBot.tsx:
// User message
<div className="bg-blue-500 text-white"> {/* Change color */}
// Assistant message
<div className="bg-green-500 text-white"> {/* Change color */}
// Available Tailwind colors
// blue-500, indigo-500, purple-500, pink-500, red-500, orange-500, yellow-500, green-500Customize Header Text
Edit components/ChatBot.tsx:
<h1 className="text-2xl font-bold">Your Title Here</h1>
<p className="text-sm">Your subtitle</p>Customize System Prompt
Edit lib/rag.ts:
const systemPrompt = `You are a helpful AI Chatbot assistant.
Answer based on provided context.
Add your custom instructions here.`;Adjust Retrieval Amount
Edit lib/rag.ts:
// Default: 3
// Change to 5 for more context
const relevantDocs = await retrieveRelevantDocs(userQuery, 5);Change Rate Limit
Edit app/api/chat/route.ts:
// 10 requests per 24 hours
// Change to 20 requests per 1 hour
const rateLimitResult = await checkRateLimit(clientIP, 20, 3600);Deployment
Deploy to Render (Recommended)
- Push to GitHub
git remote add origin <your-git-link>
git push -u origin main- Connect to Vercel
- Go to https://render.com/new
- Import your GitHub repository
- Add environment variables:
GEMINI_API_KEY- Your Google API keyREDIS_URL- Your Redis URL (optional)ADMIN_PASSWORD- Your admin password
- Deploy
- Click "Deploy"
- Visit your live URL
Deploy to Other Platforms
Vercel
vercel deployRailway
railway link
railway upNetlify
netlify deploy --prodDocker
Create Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]Build and run:
docker build -t chatbot .
docker run -p 3000:3000 \
-e GEMINI_API_KEY=your_key \
-e REDIS_URL=your_redis \
chatbotProduction Checklist
- Set strong
ADMIN_PASSWORD - Configure
REDIS_URLfor session persistence - Use HTTPS in production
- Set
NODE_ENV=production - Monitor API quotas for Gemini
- Set up error tracking (Sentry, etc.)
- Enable CORS if using from external domains
- Rate limit at CDN level for extra protection
- Set up auto-scaling if needed
- Configure backups for Redis
Troubleshooting
Build Error: MODULE_NOT_FOUND
# Solution: Clear and reinstall
rm -rf node_modules package-lock.json
npm install
npm run buildAPI Returns: "GEMINI_API_KEY is not set"
# Check:
# 1. .env.local file exists in project root
# 2. GEMINI_API_KEY=xxx is set
# 3. Restart dev server (npm run dev)Port 3000 Already in Use
# Use different port
npm run dev -- -p 3001Rate Limit Not Working
# Check Redis connection
curl http://localhost:3000/api/debug/rate-limit-status
# If not connected, set REDIS_URL or add local Redis
redis-server # macOS
docker run -d -p 6379:6379 redis:latest # DockerSessions Not Persisting
# Check Redis is running
redis-cli ping
# Returns: PONG
# Check .env.local has REDIS_URL
cat .env.local | grep REDIS_URLSlow API Responses
- Larger FAQ databases = slower embeddings
- Complex questions require more processing
- Check Google Gemini API is running properly
- Monitor network latency
Admin Endpoints Return 401
# Check .env has ADMIN_PASSWORD
cat .env | grep ADMIN_PASSWORD
# Make sure header/param matches exactly
curl -H "X-Admin-Password: your_password" \
http://localhost:3000/api/sessionsModels Not Falling Back
# Check console for [RAG] logs
# Verify GEMINI_API_KEY is valid
# Check API quota hasn't been exceeded
curl http://localhost:3000/api/debug/model-statusTech Stack
Frontend
| Technology | Version | Purpose |
|---|---|---|
| React | 18.3.1 | UI library |
| Next.js | 14.2.14 | Framework with API routes |
| TypeScript | 5 | Type safety |
| Tailwind | 4 | Styling |
| lucide-react | Latest | Icons |
Backend
| Technology | Version | Purpose |
|---|---|---|
| Node.js | 18+ | Runtime |
| Next.js API | 16.1.6 | Backend endpoints |
| Express | Built-in | Middleware (via Next.js) |
AI/ML
| Technology | Version | Purpose |
|---|---|---|
| LangChain | Latest | AI orchestration |
| Gemini API | Latest | Generative AI |
| FAISS | Latest | Vector search |
Storage/Infrastructure
| Technology | Purpose |
|---|---|
| Redis | Rate limiting + sessions (optional) |
| localStorage | Client-side caching (built-in) |
Development
| Technology | Purpose |
|---|---|
| npm | Package manager |
| TypeScript | Type checking |
| ESLint | Code quality |
| Tailwind | CSS framework |
Available Commands
# Development
npm run dev # Start dev server (http://localhost:3000)
npm run dev -- -p 3001 # Use different port
# Production
npm run build # Build for production
npm start # Start production server
# Code Quality
npm run lint # Run ESLint
# CI/CD
npm run build && npm start # Build and start
# Database
npm run redis-test # Test Redis connection (if using)
# Debug
curl http://localhost:3000/api/debug/rate-limit-status
curl http://localhost:3000/api/debug/model-statusFile Reference
| File | Purpose | Customizable |
|---|---|---|
public/CHATBOT.docx |
FAQ/Knowledge Base (MAIN) | ✅ Yes |
components/ChatBot.tsx |
Chat UI component | ✅ Yes |
lib/rag.ts |
RAG + AI logic | ✅ Yes |
lib/documentProcessor.ts |
DOCX file extraction | |
app/api/chat/route.ts |
Chat API endpoint | |
app/api/sessions/route.ts |
Session management | |
lib/rateLimiter.ts |
Rate limiting | |
app/globals.css |
Global styles | ✅ Yes |
.env.local |
Configuration | ✅ Required |
Learning Resources
- LangChain.js Documentation
- Next.js Documentation
- Google Gemini API
- FAISS Documentation
- Tailwind CSS
- TypeScript
- Redis Documentation
Feature Roadmap
Potential future enhancements:
- Real-time streaming responses
- Multi-turn conversation memory
- Feedback system for answer quality
- Admin dashboard for FAQ management
- Analytics dashboard
- User authentication
- Conversation export (PDF/JSON)
- Multi-language support
- Custom branding/white-label
- A/B testing between models
- Conversation search/archive
- Email notifications for admins
License & Attribution
- Gemini AI - Powered by Google
- FAISS - By Meta AI
- LangChain - By LangChain Inc.
- Next.js - By Vercel
- Tailwind CSS - By Tailwind Labs
✅ Completion Checklist
- Python to Next.js conversion complete
- RAG system implemented
- Session persistence (24h per IP)
- Rate limiting (10/24h per IP)
- Admin endpoints with password protection
- Gemini model fallback chain
- localStorage client-side caching
- Icons replaced (lucide-react)
- Debug endpoints added
- Comprehensive documentation
Ready to Launch?
# 1. Setup
npm install
# 2. Configure
# Create .env.local with GEMINI_API_KEY
# 3. Run
npm run dev
# 4. Open
http://localhost:3000
# 5. Ask a question!Support
For issues, questions, or feature requests:
- Check the troubleshooting section above
- Review the API documentation
- Check environment variables are set correctly
- Verify internet connection and API quotas
Last Updated: February 25, 2026
Version: 1.0.0
Status: Production Ready ✅
Happy chatting!