Frontend State Management
Relevant source files
The following files were used as context for generating this wiki page:
Frontend state management in Thoth handles the global data flow and persistence for the web application. It primarily coordinates the interactive chat experience, including message history, active conversation tracking, and synchronization with the backend API.
The system relies on Redux Toolkit for state logic and React Redux for UI integration. It implements a slice-based architecture where specific features, such as chat, manage their own state transitions and asynchronous actions.
Sources: apps/web/package.json:20-25, apps/web/src/redux/store.ts
Core Architecture
The state management layer is built around a centralized Redux store initialized via makeStore. This store aggregates multiple slices of state and applies middleware for side effects.
Store Configuration
The store uses a configuration object containing the apiUrl and handle. This configuration is injected into the store at creation time, allowing the state layer to communicate with the correct backend environment.
The diagram above shows the relationship between the configuration, the central store, and the external interfaces (API and Local Storage).
Sources: apps/web/src/redux/store.ts, apps/web/src/app/layout.tsx:21-25
Provider Integration
The StoreProvider component wraps the application root. It ensures that the Redux store is available to all client components in the Next.js component tree.
| Component | Responsibility |
|---|---|
StoreProvider | Initializes the store with environment config and provides it to React context. |
makeStore | Creates a new Redux store instance with the chat reducer. |
RootLayout | Passes PUBLIC_API_URL and SITE_HANDLE to the provider. |
Sources: apps/web/src/app/layout.tsx:28-32, apps/web/src/redux/store.ts
Chat Module State
The chat slice manages the interactive messaging system. It tracks the current draft, pending status of requests, and a list of conversations.
State Structure
The chat state maintains both the active interaction and the historical data.
- activeId: The unique identifier for the current conversation view.
- draft: The unsent text currently in the visitor's input field.
- conversations: An array of conversation objects, each containing a
threadIdand a sequence ofturns(messages). - notice: A field for displaying transient system messages or errors to the visitor.
Sources: apps/web/test/redux/slices/chat.test.ts:18-25, apps/web/test/redux/store.test.ts:75-80
Message Flow
When a visitor sends a message, the state transitions through several phases to ensure a responsive UI and data integrity.
This diagram illustrates the optimistic update pattern where the UI reflects the user's message immediately before the API responds.
Sources: apps/web/test/redux/slices/chat.test.ts:32-38, apps/web/test/redux/slices/chat.test.ts:43-52
Data Persistence
Thoth persists chat history in the browser's localStorage. This allows visitors to resume conversations after a page reload.
History Management
The system uses the loadHistory action to hydrate the Redux state from the browser's storage on startup. When a new reply is received from the agent, the updated conversation list is serialized and saved back to localStorage.
- RULE-CHAT-003: Conversations are saved newest first.
- Storage Resilience: If browser storage is blocked or throws an error, the application continues to function in-memory without crashing.
Sources: apps/web/test/redux/store.test.ts:65-71, apps/web/test/redux/store.test.ts:98-105
Thread Expiry
If the backend returns a THREAD_NOT_FOUND error (404), the state management layer identifies the thread as expired. It clears the threadId for that conversation and prompts the visitor to send the message again to initiate a new thread.
Sources: apps/web/test/redux/store.test.ts:48-52, apps/web/test/redux/store.test.ts:82-87
Technical Implementation Details
Reducer Logic
The chat logic is implemented in chatReducer. Key actions include:
asked: Optimistically adds a visitor message and clears the input.answered: Appends the agent's reply and associates the backendthreadId.failed: Handles request errors by returning the sent text to the draft input.startedNewChat: Resets the active view to a fresh conversation state.
Sources: apps/web/test/redux/slices/chat.test.ts:13-16, apps/web/test/redux/slices/chat.test.ts:70-75
Helper Utilities
The project utilizes generic-slice.ts to provide standardized patterns for state slices, ensuring consistency across different modules.
Sources: apps/web/src/redux/helpers/generic-slice.ts
Frontend state management provides a robust foundation for Thoth's interactive features by combining optimistic UI updates, resilient local persistence, and structured error handling. It ensures the visitor experience remains seamless even during network failures or thread expirations.