Next.js Frontend Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The OpenPoke frontend is a modern web application built using Next.js 14 with the App Router architecture. It serves as the primary user interface for interacting with a multi-agent orchestration stack, providing an iMessage-style chat interface, integration settings, and real-time conversation updates through polling.
The application leverages React 18, TypeScript, and Tailwind CSS for a responsive, type-safe development environment. It functions as a proxy for a Python-based FastAPI backend, routing chat messages, Gmail integration requests, and configuration updates through Next.js Route Handlers.
Sources: web/package.json:10-18, web/app/layout.tsx:4-16, README.md:10-14
Core Framework and Dependencies
The frontend environment is configured to support modern web standards and high-performance rendering.
| Dependency | Version | Purpose |
|---|---|---|
next | ^14.2.7 | Core framework (App Router) |
react | ^18.3.1 | UI Library |
tailwindcss | ^3.4.10 | Utility-first CSS styling |
typescript | ^5.6.2 | Static type checking |
clsx | ^2.1.1 | Conditional class name construction |
Sources: web/package.json:10-23, web/tsconfig.json:3-20
Application Structure and Layout
The application follows the Next.js App Router pattern, where the web/app directory defines the routing and layout logic.
Root Layout
The RootLayout component in web/app/layout.tsx serves as the entry point, wrapping all pages. It configures the global HTML structure, sets the default font antialiasing, and applies the min-h-screen background styling.
Sources: web/app/layout.tsx:10-18
Main Chat Interface
The primary application logic resides in web/app/page.tsx. It manages the state for chat messages, user input, and integration statuses.
The diagram shows the component hierarchy of the main chat page and its associated state containers.
Sources: web/app/page.tsx:162-192
Component Architecture
Chat Components
The chat interface is broken down into specialized functional components located in web/components/chat/.
- ChatMessages: Renders the message history. It distinguishes between user and assistant roles using iMessage-style bubbles (
bubble-invsbubble-out). - TypingIndicator: A CSS-animated component showing three bouncing dots when
isWaitingForResponseis true. - EmptyState: Displayed when no messages exist in the history.
Sources: web/components/chat/ChatMessages.tsx:12-65
Settings and Integrations
The SettingsModal.tsx component manages user preferences and third-party integrations, specifically Gmail via Composio. It handles:
- Timezone Detection: Automatically detects the browser timezone using
Intl.DateTimeFormatand persists it. - Gmail OAuth Flow: Initiates connection requests and opens authorization URLs.
- Local Storage Persistence: Stores
user_id,gmail_connected, anduser_timezonelocally.
Sources: web/components/SettingsModal.tsx:182-250, web/app/page.tsx:66-88
Data Flow and API Proxying
The frontend does not communicate with the LLM or tools directly. Instead, it uses Next.js Route Handlers as a proxy to the Python FastAPI backend.
Chat Sequence
When a user sends a message, the system follows an optimistic update pattern:
- Optimistic UI: The message is added to the local
messagesstate immediately. - API Call: A POST request is sent to
/api/chat. - Polling: Since the backend processing might be asynchronous, the frontend initiates a polling loop (
POLL_INTERVAL_MS = 1500) to fetch updated history until the assistant's response appears.
The sequence diagram illustrates the optimistic update and polling mechanism used to handle potentially long-running agent tasks.
Sources: web/app/page.tsx:103-160, web/app/api/chat/route.ts:25-54
API Route Endpoints
| Endpoint | Method | File Path | Purpose |
|---|---|---|---|
/api/chat | POST | web/app/api/chat/route.ts | Proxy chat messages to Python backend. |
/api/timezone | POST | web/app/api/timezone/route.ts | Sync browser timezone with the server. |
/api/gmail/connect | POST | web/app/api/gmail/connect/route.ts | Start Composio Gmail OAuth flow. |
/api/gmail/status | POST | web/app/api/gmail/status/route.ts | Check if Gmail connection is active. |
Sources: web/app/api/chat/route.ts:25, web/app/api/timezone/route.ts:5, web/app/api/gmail/connect/route.ts:5
Styling and Theming
OpenPoke uses Tailwind CSS with a custom configuration to achieve a clean, "Apple-like" aesthetic.
- Custom Colors: Defines a
brandcolor palette (shades of blue) intailwind.config.ts. - Global Classes: Custom components like
.btn,.input, and.cardare defined inweb/app/globals.cssusing the@applydirective. - Chat Bubbles: Specialized styling for chat interactions:
.bubble-out: Brand blue background, white text (User)..bubble-in: Gray background, dark text (Assistant).- Tail modifiers (
.bubble-tail-out) to adjust corner rounding for message groupings.
Sources: web/tailwind.config.ts:10-25, web/app/globals.css:10-55
State Management and Persistence
The application relies on React hooks (useState, useCallback, useEffect) and LocalStorage for state management.
- useSettings Hook: Encapsulates the logic for reading and writing settings (like timezone) to
localStorage. - History Management: Chat history is fetched and cleared using dedicated API routes. The
handleClearHistoryfunction resets the local state after a successfulDELETErequest to/api/chat/history.
Sources: web/components/SettingsModal.tsx:10-30, web/app/page.tsx:135-147
OpenPoke's frontend architecture prioritizes a responsive user experience by combining React's reactive state management with a robust API proxy layer, ensuring seamless integration between the web UI and the underlying Python multi-agent system.