Skip to content

AI Chat Widget

A production-ready, Claude Docs-inspired AI chat widget that provides instant, conversational answers about your documentation site. Built with security-first principles using Google Cloud Run and Gemini API.

  • Security First


    Defense-in-depth security model with prompt injection safeguards, secret management, and XSS prevention.

    Security Documentation

  • Modular Architecture


    MVVM pattern with separated concerns: Model, View, ViewModel, and reusable utilities in lib/.

    Architecture Guide

  • Easy Deployment


    Deploy to Google Cloud Run with Secret Manager integration. Free tier covers typical usage.

    Deployment Guide

  • Plug & Play


    Integrate into any Zensical or MkDocs Material site with minimal configuration.

    Integration Guide


Why Build This?

The Problem

Documentation sites are static. Users often struggle to find specific information across many pages, especially on mobile. Traditional search returns page links, not answers.

The Solution

An AI-powered chat widget that:

  • Answers questions directly - No need to read entire pages
  • Understands context - Knows about the site and its content
  • Works everywhere - Desktop, tablet, mobile
  • Respects privacy - No conversation logging, session-based only

Inspiration

Inspired by Claude's documentation chat which provides an excellent user experience for finding information quickly.


Key Features

For Users

Feature Description
Instant Answers Get responses about site content without searching
Conversation Memory Follow-up questions maintain context
Mobile Friendly Full-screen modal on mobile, sidebar on desktop
Dark Mode Automatic theme detection
Rate Limited Prevents abuse, provides friendly feedback

For Developers

Feature Description
MVVM Architecture Clean separation of concerns for maintainability
No Build Step Pure JavaScript, no bundler required
Configurable Easy to customize API endpoints, styling, behavior
Secure by Default XSS prevention, CORS, prompt injection safeguards
Observable Prefixed logging ([AI Chat]) for easy debugging

Component Overview

┌─────────────────────────────────────────────────────────────┐
│  Frontend (Your Static Site)                                │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  src/                    lib/                         │  │
│  │  ├── main.js             ├── api.js                   │  │
│  │  ├── model.js            ├── config.js                │  │
│  │  ├── view.js             ├── logger.js                │  │
│  │  └── view-model.js       └── message-parser.js        │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              │ HTTPS + CORS
┌─────────────────────────────────────────────────────────────┐
│  Backend (Cloud Run)                                        │
│  ├── Flask Proxy Service                                    │
│  ├── Prompt Injection Safeguards                            │
│  ├── CORS Validation (dynamic Codespaces support)           │
│  └── Secret Manager Integration                             │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  AI Layer (Gemini API)                                      │
│  └── Gemini 2.0 Flash - Fast, conversational responses      │
└─────────────────────────────────────────────────────────────┘

Frontend Components

Component Location Purpose
main.js src/ Application entry point, composition root
model.js src/ State management (messages, loading, isOpen)
view.js src/ DOM manipulation, event binding (dumb view)
view-model.js src/ Business logic, bridges View and Model
api.js lib/ Backend communication service
config.js lib/ Configuration (API URL, limits, etc.)
logger.js lib/ Prefixed logging utility
message-parser.js lib/ Markdown parsing for responses

Backend Components

Component Purpose
main.py Flask service with Gemini integration
CORS Handler Regex-based origin validation (supports Codespaces)
Prompt Guard 10+ pattern detection for injection attempts
Secret Manager Secure API key retrieval

Quick Start

Prerequisites

  • Google Cloud account with billing enabled
  • Gemini API key (free tier available)
  • Zensical or MkDocs Material site

1. Deploy Backend

# Clone the backend
git clone https://github.com/BA-CalderonMorales/agent-chat-proxy

# Deploy to Cloud Run
gcloud run deploy agent-chat-proxy \
  --source . \
  --region us-central1 \
  --allow-unauthenticated

2. Add Frontend

Copy the docs/assets/js/chat-widget/ directory to your site and add to your template:

<!-- In your overrides/main.html -->
{% block scripts %}
  {{ super() }}
  <script src="{{ 'assets/js/chat-widget/lib/config.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/lib/logger.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/lib/api.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/lib/message-parser.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/src/model.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/src/view.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/src/view-model.js' | url }}"></script>
  <script src="{{ 'assets/js/chat-widget/src/main.js' | url }}"></script>
{% endblock %}

3. Configure

Update lib/config.js with your Cloud Run URL:

const ChatConfig = {
  API_URL: 'https://your-service-name.run.app/chat',
  // ...
};

Full Integration Guide


Cost Estimate

Designed for personal/portfolio sites with < $5/month target:

Service Cost Notes
Cloud Run Free 2M requests/month free tier
Gemini API Free Preview model, generous limits
Secret Manager ~$0.10/month Per secret version accessed
Total < $1/month Typical portfolio usage

Limitations

This implementation is designed for personal projects with moderate traffic:

Limitation Reason Mitigation
Client-side rate limiting Can be bypassed Server-side limits in roadmap
No user auth Public by design CORS + prompt guards
Pattern-based injection defense Not ML-based Covers common attacks
500 char input limit Cost control Sufficient for questions

For enterprise use, consider adding Cloud Armor, OAuth, and advanced logging.


Roadmap

  • [ ] Server-side rate limiting (IP-based)
  • [ ] Conversation export
  • [ ] Analytics dashboard
  • [ ] Multi-language support
  • [ ] Custom persona configuration
  • [ ] Webhook integrations

  • Security

    Defense-in-depth model, threat analysis, testing procedures

  • Architecture

    MVVM pattern, file structure, component details

  • Deployment

    Cloud Run setup, Secret Manager, CI/CD

  • Integration

    Plug-and-play guide for other sites