A modern Next.js chat application that provides a ChatGPT-like interface for interacting with AI agents. Features real-time streaming responses, authentication, and markdown rendering.
🌐 Live Application: https://aiagent.kingsley-api.name.ng/
Try out the application with a live demo at the link above.
- Real-time Chat Interface: ChatGPT-style chatbox with streaming responses
- Authentication: Secure login, registration, and logout with httpOnly cookies
- Data Validation: Runtime type-safe validation with Zod for all API endpoints
- Streaming API: Server-Sent Events (SSE) for real-time message streaming
- Markdown Rendering: Rich markdown support with syntax highlighting
- Auto-logout on 401: Automatic logout and redirect when authentication expires
- Route Protection: Protected routes with automatic redirect to login
- Dark Mode Support: Built-in dark mode styling
- Comprehensive Testing: Full test coverage with Jest and React Testing Library
- Framework: Next.js 16.1.1 (App Router)
- Language: TypeScript
- Validation: Zod for runtime type-safe validation
- Styling: Tailwind CSS 4
- Markdown: react-markdown with remark-breaks
- Testing: Jest, React Testing Library, @testing-library/user-event
- Authentication: Token-based with httpOnly cookies
- Node.js 18+
- npm, yarn, pnpm, or bun
- Clone the repository:
git clone https://github.com/kingrocfella/agentic-ai-client
cd agentic-ai-client- Install dependencies:
npm install- Create a
.env.localfile in the root directory:
AGENT_API_BASE_URL=http://localhost:9000
COOKIE_AGE_DAYS=7
NODE_ENV=developmentnpm run devOpen http://localhost:3000 in your browser.
- Create a
.envfile in the root directory:
AGENT_API_BASE_URL=http://localhost:9000
COOKIE_AGE_DAYS=7
NODE_ENV=production- Build and run with Docker Compose:
docker-compose up -dThe application will be available at http://localhost:3000.
- Build the Docker image:
docker build -t ai-agent-client .- Run the container:
docker run -p 3000:3000 --env-file .env ai-agent-clientNote: The Dockerfile uses Next.js standalone output mode for optimized production builds.
ai-agent-client/
├── app/
│ ├── api/
│ │ ├── auth/ # Authentication API routes
│ │ │ ├── login/ # POST /api/auth/login
│ │ │ ├── logout/ # GET /api/auth/logout
│ │ │ └── register/ # POST /api/auth/register
│ │ └── chat/ # GET /api/chat - Streaming chat endpoint
│ ├── components/ # React components
│ │ ├── ChatBox.tsx # Main chat interface
│ │ ├── MarkdownRenderer.tsx
│ │ ├── SendIcon.tsx
│ │ └── LoadingSpinner.tsx
│ ├── lib/ # Utility functions
│ │ ├── api.ts # Client-side API functions
│ │ └── auth.ts # Authentication utilities
│ ├── login/ # Login/Register page
│ └── page.tsx # Home page (protected)
├── proxy.ts # Route protection middleware
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose configuration
└── jest.config.js # Jest configuration
- Login/Register: Users authenticate via
/loginpage - Token Storage: Access tokens stored in httpOnly cookies with
sameSite: "strict" - Protected Routes: Home page requires authentication (handled by
proxy.ts) - Auto-logout: On 401 responses, cookies are cleared and user is redirected to login
- Logout: Explicit logout clears cookies and calls external logout API
All API routes use Zod for runtime type-safe validation:
- Request Validation: All incoming data is validated against Zod schemas
- Response Validation: External API responses are validated for type safety
- Clear Error Messages: Validation failures return detailed error information
- Type Safety: TypeScript types are automatically inferred from schemas
See VALIDATION.md for detailed documentation on validation implementation.
Example validation error response:
{
"error": "Validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}Run tests with:
# Run all tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverageThe application uses Server-Sent Events (SSE) for real-time streaming:
- Client creates
EventSourceconnection to/api/chat - Next.js API route proxies request to external AI agent API
- Response stream is forwarded to client
- Client processes chunks and updates UI in real-time
- Uses
react-markdownwithremark-breaksplugin - Supports headings, lists, code blocks, inline code, blockquotes
- Custom styling with Tailwind CSS
- Implemented via
proxy.ts(Next.js proxy pattern) - Protects home page (
/) - Allows
/loginand/api/*routes without authentication - Redirects unauthenticated users to login with redirect parameter
npm run build
npm startnpm run lint