# Conversation list demo: source

> The code that makes the Conversation list demo work, walked through snippet by snippet.

A returning visitor can reopen an earlier conversation and carry on. On the page's side that takes one attribute and one event listener.

## Turn the list on

One attribute on the chat element adds a Conversations button. The element fetches the list itself.

```ts file=src/demos/shared/useDemoElement.ts
el.setAttribute('agent', handle)
if (live.current.conversationList) el.setAttribute('conversation-list', '')
```

## Whose list it is

The list holds the session user's own conversations, so your server's user id decides it.

```ts file=server/guide-session/handler.ts
body: JSON.stringify({ user: { externalId: visitor }, agent, createUserIfNeeded: true }),
```

## Hear which conversation is open

The element fires an event when a conversation is saved or the visitor picks an earlier one.

```tsx file=src/demos/orbit/index.tsx
const on = (e: Event) => onConversation((e as CustomEvent<ConversationEventDetail>).detail)
node.addEventListener('mindset:conversation', on)
```

## Saved or resumed

The page turns each event into what it shows, so it never claims a save that didn't happen.

```ts file=src/demos/orbit/history.ts
if (detail?.replacedBecause === 'switched') return { kind: 'resumed', conversationId: id, picks: (state.kind === 'resumed' ? state.picks : 0) + 1 }
if (state.kind !== 'idle' && state.conversationId === id) return state
return { kind: 'saved', conversationId: id }
```
