This is an extended version of the original OpenAI ChatKit Starter Template, enhanced with:
- β Docker support for containerized deployments
- β AWS App Runner deployment guide with full troubleshooting
- β Multi-platform build support (ARM64/AMD64)
- β Production-ready configuration for Vercel and AWS
- β Easy integration as a chatbot widget in other apps (Lovable, React, etc.)
This repository is the simplest way to bootstrap a ChatKit application. It ships with a minimal Next.js UI, the ChatKit web component, and a ready-to-use session endpoint so you can experiment with OpenAI-hosted workflows built using Agent Builder.
This extended version was developed during the OpenAI Agent Builder course by Diogo Alves de Resende. The course project involved building a Deep Research Agent with multi-agent orchestration:
Agent Workflow:
- Topic extraction from user input
- Guardrails validation
- Keyword generation (4 strategic keywords)
- User approval
- While loop for deep research on each keyword
- Final summarization
The Challenge: The course didn't cover how to integrate ChatKit as a widget in external applications. I solved this by adding Docker containerization, AWS deployment, and a reusable React widget component.
Known Issues in Agent Builder (as of course completion):
- π Variable selection in dropdown menus sometimes selects wrong variables
- π Web Search tool conflicts with MCP Google Calendar - remove Web Search if using Calendar
Live Demo: minimal-persona-showcase.lovable.app
- Next.js app with
<openai-chatkit>web component and theming controls - API endpoint for creating a session at
app/api/create-session/route.ts - Config file for starter prompts, theme, placeholder text, and greeting message
npm installCopy the example file and fill in the required values:
cp .env.example .env.localYou can get your workflow id from the Agent Builder interface, after clicking "Publish":
You can get your OpenAI API key from the OpenAI API Keys page.
Update .env.local with the variables that match your setup.
OPENAI_API_KEYβ This must be an API key created within the same org & project as your Agent Builder. If you already have a differentOPENAI_API_KEYenv variable set in your terminal session, that one will take precedence over the key in.env.localone (this is how a Next.js app works). So, please rununset OPENAI_API_KEY(set OPENAI_API_KEY=for Windows OS) beforehand.NEXT_PUBLIC_CHATKIT_WORKFLOW_IDβ This is the ID of the workflow you created in Agent Builder, which starts withwf_...- (optional)
CHATKIT_API_BASE- This is a customizable base URL for the ChatKit API endpoint
Note: if your workflow is using a model requiring organization verification, such as GPT-5, make sure you verify your organization first. Visit your organization settings and click on "Verify Organization".
npm run devVisit http://localhost:3000 and start chatting. Use the prompts on the start screen to verify your workflow connection, then customize the UI or prompt list in lib/config.ts and components/ChatKitPanel.tsx.
You have multiple deployment options:
Step-by-step guide:
-
Fork this repository (or use the original template)
-
Create a Vercel account at vercel.com if you don't have one
-
Import your repository:
- Go to Vercel Dashboard β "Add New" β "Project"
- Import your forked ChatKit repository from GitHub
-
Configure environment variables (BEFORE deploying):
- In the Vercel import screen, add these environment variables:
OPENAI_API_KEY=sk-proj-your-api-key-hereNEXT_PUBLIC_CHATKIT_WORKFLOW_ID=wf_your-workflow-id-here
- In the Vercel import screen, add these environment variables:
-
Deploy:
- Click "Deploy"
- Wait for the build to complete (~2 minutes)
-
Add domain to OpenAI Allowlist (CRITICAL!):
- After deployment, Vercel assigns you a domain like
your-app.vercel.app - Go to OpenAI Domain Allowlist
- Click "Add domain" and enter your Vercel domain (without
https://) - Save and wait a few minutes for propagation
- After deployment, Vercel assigns you a domain like
-
Test your app:
- Visit your Vercel URL
- ChatKit should load and work correctly
That's it! Now you can use this URL in the Lovable widget component.
For a comprehensive guide on deploying with Docker to AWS App Runner (including ECR setup, health check configuration, and troubleshooting), see AWS_DEPLOYMENT.md.
Quick Docker setup:
# 1. Build the Docker image (Mac M-series users: use --platform linux/amd64)
docker buildx build \
--platform linux/amd64 \
--build-arg NEXT_PUBLIC_CHATKIT_WORKFLOW_ID="wf_..." \
-t chatkit-app:latest \
--load \
.
# 2. Test locally
docker run -p 3000:3000 \
-e OPENAI_API_KEY="sk-proj-..." \
-e NEXT_PUBLIC_CHATKIT_WORKFLOW_ID="wf_..." \
chatkit-app
# Or use docker-compose
docker-compose upImportant notes:
- On Mac M1/M2/M3, always use
--platform linux/amd64for AWS compatibility - Each user must provide their own
NEXT_PUBLIC_CHATKIT_WORKFLOW_IDvia--build-arg - See AWS_DEPLOYMENT.md for complete AWS deployment instructions
IMPORTANT: Before your deployed app can work, you MUST add your deployment domain to the OpenAI Domain Allowlist.
-
Get your deployment URL:
- Vercel:
your-app-name.vercel.app - AWS App Runner:
xxxxxxxx.eu-west-1.awsapprunner.com - Custom domain:
chat.yourdomain.com
- Vercel:
-
Add to OpenAI Allowlist:
- Go to OpenAI Domain Allowlist
- Click "Add domain"
- Enter your domain (without
https://, just the domain part) - Save
-
Wait a few minutes for the changes to propagate, then test your app
Without this step, ChatKit will fail to load with CORS errors.
Once deployed, you can easily integrate this chatbot as a floating widget in any React application (Lovable, Next.js, Vite, etc.).
Create a ChatbotWidget.tsx component in your frontend app:
import { useState } from "react";
import { MessageCircle, X } from "lucide-react";
interface ChatbotWidgetProps {
chatbotUrl?: string;
}
const ChatbotWidget = ({
chatbotUrl = "https://your-chatbot.vercel.app"
}: ChatbotWidgetProps) => {
const [isOpen, setIsOpen] = useState(false);
const toggleChatbot = () => {
setIsOpen(!isOpen);
};
return (
<>
{/* Chatbot Iframe */}
<div
className={`fixed bottom-24 right-4 md:right-6 w-[calc(100vw-2rem)] md:w-[400px] h-[500px] md:h-[600px] bg-background border border-border rounded-2xl shadow-lg z-[998] transition-all duration-300 ${
isOpen
? "opacity-100 scale-100 pointer-events-auto"
: "opacity-0 scale-95 pointer-events-none"
}`}
>
<iframe
src={chatbotUrl}
className="w-full h-full rounded-2xl"
title="Chatbot"
allow="microphone"
/>
</div>
{/* Floating Button */}
<button
onClick={toggleChatbot}
className={`fixed bottom-4 md:bottom-6 right-4 md:right-6 w-14 h-14 md:w-16 md:h-16 bg-primary hover:bg-primary/90 text-primary-foreground rounded-full flex items-center justify-center shadow-lg z-[999] transition-all duration-300 hover:scale-110 active:scale-95`}
aria-label={isOpen ? "Close chatbot" : "Open chatbot"}
>
{isOpen ? (
<X className="h-6 w-6 md:h-7 md:w-7" />
) : (
<MessageCircle className="h-6 w-6 md:h-7 md:w-7" />
)}
</button>
</>
);
};
export default ChatbotWidget;import ChatbotWidget from "@/components/ChatbotWidget";
function App() {
return (
<div>
{/* Your app content */}
<ChatbotWidget chatbotUrl="https://your-deployed-chatbot.vercel.app" />
</div>
);
}- Deploy this ChatKit app to Vercel or AWS
- Add the domain to OpenAI allowlist
- Create the
ChatbotWidgetcomponent in your Lovable project - Pass your deployment URL as the
chatbotUrlprop - The chatbot will appear as a floating button in the bottom-right corner
Live Demo: See the widget in action at minimal-persona-showcase.lovable.app
- Adjust starter prompts, greeting text, chatkit theme, and placeholder copy in
lib/config.ts. - Update the event handlers inside
components/ChatKitPanel.tsxto integrate with your product analytics or storage.


