Architecture Strategy
To build a robust Agent UI (like the one in this course) using Vibe Coding, do not just tell the AI to "Make an app." You must guide it through a structured pattern.
We recommend the Redux Pattern (even without using the Redux library itself) because it forces the AI to be predictable.
The Mental Model
In this architecture, the View never changes data directly. It dispatches an Action, which flows through Middleware (for API calls/Side Effects) before reaching the Reducer to update the State.
Glossary of Terms
- Store: The single source of truth. It is a container that holds your entire application's data in one place.
- State: A snapshot of data at a specific moment in time (e.g.,
isLoading: true,user: null). - Action: A plain object describing what happened (e.g.,
{ type: 'LOGIN_CLICKED' }). It does not change data itself; it just announces an event. - Middleware: The "Man in the Middle." It sits between the Action and the Reducer to handle side effects like API calls, logging, or delays.
- Reducer: A pure function that takes the Current State and an Action, calculates the logic, and returns the New State.
- Mutation: The act of changing the state. In this pattern, we don't modify variables directly; we replace the old state object with a new one.
The Vibe Coding Workflow
This "Cheat Sheet" outlines the 7 sequential steps required to prompt an AI effectively for complex UIs.
| # | Phase | Critical Actions & Output |
|---|---|---|
| 1 | User Journeys | Map specific user actions, entry points, and success states. |
| 2 | Define State | Create the |
| 3 | Define Actions | List event types ( |
| 4 | Map to Views | Connect State to UI Components. Determine conditional rendering logic (e.g., |
| 5 | Logic & Auth | Implement Reducers and Side Effects. Handle the complexity of OAuth/Firebase and asynchronous data fetching. |
| 6 | Persistence | Define hydration strategies. Use |
| 7 | Security | Crucial Step: Secure API keys, sanitize inputs, and remove sensitive console logs before deployment. |
Detailed Breakdown
Recommendation: Use an AI agent or coding tool while implementing these steps to explore different architectural patterns.
Software best practices evolve rapidly. Before committing to a specific implementation, research the latest standards for your stack. The code snippets and examples provided below are placeholders meant to illustrate the "Vibe Coding" mental model; they are not comprehensive production specifications.
Below is the detailed explanation of the process visualized above.
Step 1: Describe the User Journeys
First, write down exactly what the user does.
- Journey A: User lands on the page and sees a "Login with Google" button.
- Journey B: User types a message in the chat box and hits enter.
- Journey C: User enters their Gemini API Key in a settings modal.
- Journey D: User views a visual canvas of their agent graph.
Step 2: Define the State (The Source of Truth)
In modern UI development, UI = f(State). The User Interface is just a function of the data currently held in memory. Tell the AI to define the state interface first.
interface AppState {
// Authentication
user: User | null;
authStatus: 'idle' | 'authenticated' | 'anonymous';
// The Conversation
messages: Array<{
role: 'user' | 'model';
text: string;
timestamp: number;
}>;
// Configuration
apiKey: string | null;
isSettingsOpen: boolean;
}
Step 3: Define Actions (Interactions)
Define how the state changes. This prevents "Spaghetti Code" where random components modify data unpredictably.
LOGIN_SUCCESS: SetsauthStatusto 'authenticated'.SEND_MESSAGE: Adds a user message to themessagesarray.RECEIVE_RESPONSE: Adds a model message to themessagesarray.OPEN_SETTINGS: TogglesisSettingsOpento true.
Step 4: Map State to Views (Screens)
Now, ask the AI to build components based on that state.
- If
authStatus === 'anonymous', Show<LoginScreen />. - If
authStatus === 'authenticated', Show<MainLayout />. - Inside
<ChatWindow />, render the list ofmessages.
Step 5: Authentication & Login
Explicitly tell the AI how to handle security.
- Requirement: Use Firebase Auth or OAuth.
- Action: When the user clicks login, trigger the provider popup. On success, dispatch
LOGIN_SUCCESS.
Step 6: Data Models & Persistence
Decide where the data lives.
- Ephemeral: Chat history might live only in React State (RAM) for this session.
- Persistent: The API Key should be stored in
localStorage(Client-side) so it persists across reloads but never leaves the browser.
Step 7: Security & Credential Management
When Vibe Coding, you must explicitly instruct the AI on security boundaries:
- Rule: "Never hardcode API keys."
- Rule: "The User's Gemini API Key must be stored in the browser's LocalStorage and only passed to the AI model function when needed."
- Rule: "Do not log sensitive data to the console in production."