AI
Next.js
OpenAI
TypeScript
Portfolio

Building an AI-Powered Chat Widget for My Portfolio

December 7, 2025
12 min read

How I built a sophisticated AI chat widget with conversation memory, first-person responses, and mobile-first design to create meaningful visitor interactions on my portfolio site.

Building an AI-Powered Chat Widget for My Portfolio

The Challenge

As a Computer Engineering student, I wanted to create an interactive way for visitors to my portfolio website to learn more about me and my work. Traditional portfolio sites are static, but I wanted something dynamic that could engage visitors and provide personalized responses about my skills, projects, and experience.

The Solution: A Two-Stage AI Pipeline with Conversation Memory

I implemented a sophisticated chat widget using OpenAI's API with a carefully designed two-stage pipeline that includes conversation history awareness and first-person perspective responses.

Stage 1: Intent Classification with History Context

The first stage determines whether a visitor's question is appropriate and relevant, now considering conversation history for better follow-up handling:

User: "What programming languages do you know?"

→ { "intent": "on_topic", "fieldsNeeded": ["skills.languages"] }

User: "Tell me about yourself"

→ { "intent": "on_topic", "fieldsNeeded": ["about", "hero", "summary", "experience", "education", "skills", "highlights"] }

User: "Have you used n8n before?"

→ { "intent": "on_topic", "fieldsNeeded": ["skills", "projects"] }

Stage 2: Context-Aware Response Generation

For on-topic questions, the system extracts only the relevant information from my portfolio data and generates personalized responses in first-person perspective:

The AI now responds as "I" rather than referring to "Michael" in third person, creating a more natural conversational experience.

Advanced Features

Conversation Memory

Tracks the last 6 messages for context awareness

Handles follow-up questions intelligently

Maintains conversation flow across multiple interactions

Smart Context Extraction

Auto-includes "projects" and "skills" for technology questions

Always includes contact info for reach/contact inquiries

Comprehensive data for "tell me about yourself" questions

Enhanced Link Rendering

The chat widget now properly handles markdown-style links and plain URLs:

const renderMessageContent = (content: string) => {

// First, handle markdown-style links [text](url)

const markdownLinkRegex = /[([^]]+)](([^)]+))/g;

// Then handle plain URLs...

};

Mobile-First Design

  • Full-screen chat on mobile devices
  • Prevents input zoom with 16px minimum font size
  • Smooth animations with requestAnimationFrame
  • Touch-optimized interactions
  • User Experience Enhancements

  • Popup Bubble: Appears after 8 seconds encouraging interaction
  • Progress Indicators: Real-time pipeline stages with thinking messages
  • Message History: Persistent conversations with proper scrolling
  • Auto-focus: Input focuses when chat opens
  • Keyboard Shortcuts: Shift+Enter for new lines, Enter to send
  • Technical Implementation

    Frontend Architecture

    Built with React and TypeScript, featuring:

  • State Management: Complex state handling for messages, loading, and UI states
  • Responsive Design: Desktop fixed-size window, mobile full-screen experience
  • Performance: Optimized scrolling and animations
  • Accessibility: Proper ARIA labels and keyboard navigation
  • Backend API Design

    The /api/chat endpoint implements robust security and performance:

  • Rate Limiting: 20 requests per 15-minute window with automatic IP banning
  • Conversation History: Last 6 messages passed to maintain context
  • Context Extraction: Dot-notation field extraction (e.g., "skills.languages", "projects[0]")
  • Response Sanitization: Length limits and content filtering
  • Security Measures

    interface RateLimitData {

    requests: number;

    firstRequest: number;

    violations: number;

    bannedUntil?: number;

    }

    const RATE_LIMITS = {

    requests: 20, // 20 questions per window

    windowMs: 15 * 60 * 1000, // 15 minutes

    banThreshold: 10, // Ban after 10 violations

    banDuration: 24 * 60 * 60 * 1000 // 24 hours

    };

    User Experience Flow

    1. Discovery: Popup bubble appears after 8 seconds: "Questions about me?"

    2. Interaction: Click to open responsive chat window

    3. Question: Type question about background, skills, or projects

    4. Processing: See real-time progress:

  • "AI classifying message intent..."
  • "AI determining context..."
  • "AI responding..."
  • 5. Response: Receive personalized first-person answer with clickable links

    6. Conversation: Continue natural dialogue with full context awareness

    Why This Approach Works

    Efficiency

    Context-aware responses reduce token usage

    Two-stage pipeline prevents unnecessary API calls

    Smart field extraction minimizes data transfer

    Safety & Reliability

    Strict intent classification prevents inappropriate content

    Comprehensive rate limiting and IP banning

    Response sanitization and error handling

    User Experience

    First-person responses create personal connection

    Conversation memory enables natural follow-ups

    Mobile-optimized interface works seamlessly across devices

    Progress transparency builds trust

    Technical Stack

    Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS

    Backend: Next.js API Routes with Edge Runtime

    AI: OpenAI GPT-4o-mini with custom engineered prompts

    UI Components: Shadcn UI with Lucide React icons

    State Management: React hooks with complex state interactions

    Deployment: Vercel with environment variable protection

    Future Enhancements

    I'm considering adding:

    Voice Input: Speech-to-text for accessibility and hands-free interaction

    File Uploads: Resume or project file sharing capabilities

    Analytics Dashboard: Track common questions and engagement metrics

    Multi-language Support: Expand to international audiences

    Smart Suggestions: Context-aware question recommendations based on conversation history

    This AI chat widget represents the perfect intersection of my engineering background and user experience design. It demonstrates how modern web technologies can create meaningful, interactive experiences that go far beyond static portfolio content while maintaining professional standards and technical excellence.

    Michael Perkins — Portfolio