# Conversation history persists across page refreshes

- **Pattern:** `ab-000151` (`ai-chat-visibility.input-and-history.conversation-history-persisted`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000151
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000151)

## Why it matters

The Vercel AI SDK's `useChat` hook stores messages exclusively in React component state — a page refresh destroys the entire conversation with no recovery path. For any application where users build on prior context (debugging sessions, multi-step workflows, ongoing support threads), this is a reliability failure under iso-25010:2011: the system cannot maintain its service when subjected to a routine browser event. Users who lose history mid-workflow may lose irreplaceable problem context. Data-integrity also demands that committed user interactions not vanish silently; a conversation a user considers saved is, in effect, corrupted when it disappears.

## Severity rationale

Critical because in-memory-only storage guarantees total data loss on every page refresh, destroying user work with no recovery mechanism.

## Remediation

Persist messages to `localStorage` on every state change and load them as `initialMessages` on mount in `src/components/chat/ChatWindow.tsx`.

```tsx
const { messages } = useChat({
  initialMessages: JSON.parse(
    localStorage.getItem('chat-history') || '[]'
  ),
});

useEffect(() => {
  localStorage.setItem('chat-history', JSON.stringify(messages));
}, [messages]);
```

For authenticated users, replace `localStorage` with a database-backed route at `app/api/chat/history/route.ts` — write after each exchange and read on mount. `localStorage` is an acceptable fallback for anonymous sessions but must not be the only mechanism for logged-in users where history is a product guarantee.

## Detection

- **ID:** `conversation-history-persisted`
- **Severity:** `critical`
- **What to look for:** Enumerate all persistence mechanisms in the chat component: `localStorage.setItem()` calls, database writes on each message (via API routes), state management libraries (Zustand, Redux) with persistence middleware, or IndexedDB usage. Count how many of these are present. The Vercel AI SDK's `useChat` hook does NOT persist history by default — it is in-memory only. Check whether messages are loaded on component mount from a persistent source.
- **Pass criteria:** Conversation messages are persisted to localStorage, sessionStorage, a database, or another durable store via at least 1 persistence mechanism. On page refresh, the conversation history is restored. Report even on pass: "History persisted via [mechanism] — N messages restored on mount."
- **Fail criteria:** Conversation history exists only in React state (in-memory). Refreshing the page loses all history. No persistence mechanism is detected.
- **Do NOT pass when:** Messages are saved only in a Zustand store without a `persist` middleware configured — in-memory-only Zustand is NOT a pass. Also do NOT pass when localStorage writes exist but `initialMessages` or equivalent mount-time loading is missing.
- **Skip (N/A) when:** The interface is explicitly designed as ephemeral (e.g., a single-question widget, a kiosk mode, or a demo that intentionally resets each session). Signal: a visible "this conversation is not saved" notice, or product documentation describes the interface as ephemeral.
- **Detail on fail:** `"Conversation messages stored only in useChat in-memory state — no persistence to localStorage or database; all history lost on page refresh"`
- **Remediation:** In your chat component at `src/components/chat/ChatWindow.tsx`, add persistence:

  ```tsx
  const { messages } = useChat({
    initialMessages: JSON.parse(localStorage.getItem('chat-history') || '[]'),
  });
  useEffect(() => {
    localStorage.setItem('chat-history', JSON.stringify(messages));
  }, [messages]);
  ```

  For production applications with logged-in users, persist to a database via `app/api/chat/history/route.ts` after each exchange and load history on mount.
- **Cross-reference:** For database-backed persistence patterns and data modeling, the Database Layer Audit covers schema design for conversation storage.

## External references

- iso-25010 reliability

Taxons: data-integrity

HTML version: https://auditbuffet.com/patterns/ab-000151
