> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentcard.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Showing stores and their menus

> Render a card for each store near the shopper, then the menu of the one they pick.

A food delivery order starts with a choice of store. The shopper asks for a taco, and Agentcard answers with the taco places near them that deliver. Your chat shows a card for each store, with its picture, its name, and its delivery time. The shopper taps one, and the next cards are that store's menu.

## Render a card for each store

Each store the reply names reaches `sendLink` as a `store` link, up to eight for each answer, in the order the reply names them.

```ts chat.ts theme={null}
const turn = buyFor(shopper.id).turn(message, {
  sendLink: (link) => {
    if (link.kind === 'store') return sendStoreCard(shopper.id, link); // your code
    if (link.kind === 'product') return sendProductCard(shopper.id, link); // the menu items
    return deliverStepLink(shopper.id, link);
  },
});
```

A `store` link carries these fields:

| Field | Type | What it holds |
| - | - | - |
| `title` | string | The store's name. |
| `url` | string or null | The store's page at the merchant. |
| `storeId` | string | Agentcard's id for the store. It holds no link. |
| `etaMinutes` | number or null | The delivery estimate in minutes, or null when the store showed none. |
| `imageUrl` | string or null | The picture the store's card shows at the merchant, or null when it shows none. |

Show each store as a card with the picture and an Order here button. `result.stores` carries the same stores for your code, each with its `url` and `linkSent`.

The model reads each store by its `store_id`, name, and `eta_minutes`, and never its page. It reads `store_links_sent`, the number of store cards the shopper holds, and its description tells it to ask which store in one short line instead of listing them again.

Agentcard lists stores only for an answer whose reply presents them as a choice. A turn that searched stores on its way to a menu, or one that shows a cart, lists none.

## Pick a store

When the shopper picks a store by its name, its place in the list, or a tap on its card, the model passes that `store_id`, and Agentcard selects exactly that store before its agent answers. The products Agentcard finds next are from that store, so the next answer is the store's menu as `product` links.

A tap on a card needs no id from your app. The Order here button sends the shopper's words, such as:

```text theme={null}
Order from Tacos El Grullense
```

The tool reads the store's name alone, the name with `please`, and `order here` or `this place` as a pick of a store the last answer listed. A shopper who answers only with a place in the list, such as `the second one` or `2`, picks the store at that place, whether or not the model passed the id.

A dish beside the store's name is a search, not a pick. `order tacos from el farolito` searches for tacos.

A pick starts no search, so it gets no instant reply. Your chat can still react: "Acknowledging the shopper" shows when the 👀 or the text appears.

Your own code can pick too. A card's button can call `buy.answer` with the link's `storeId`:

```ts store-button.ts theme={null}
const result = await buyFor(shopper.id).answer({
  ask: link.title ?? '',
  confirm: false,
  new_order: false,
  store_id: link.storeId, // from the store link, never typed by the shopper
});
```

`result.store_pick` says what happened: the store's id and name, and `selected`, whether the merchant took the selection. When it did not, Agentcard's agent selects the store itself. The model reads the same `store_pick`.

### Handle a store that Agentcard no longer holds

Agentcard keeps the stores of a search for 15 minutes, and a newer search replaces them. A pick of a store Agentcard no longer holds selects nothing, and the model reads that it should search again with the shopper's words.

## Show the menu

The menu arrives as `product` links, one for each dish, with the same fields as any product card. The dishes of one store share the store's one page, so three dishes in a reply are three cards that open the same page. Render them as described in "Showing products and carting the one the shopper picks", and cart the one the shopper taps.

A later turn whose reply presents the stores again sends their cards again, so every store the reply names arrives with its card. A store link that your `sendLink` throws on counts as not sent.

## Check it in the sandbox

1. Send "get me tacos" to your agent as a test shopper.
2. Check that store cards arrive, each with a picture, a name, and a delivery time, and that the reply asks which store in one short line.
3. Tap a card. Check that the next cards are that store's menu and the chat ran no store search.
4. Send "the second one" after a new store search. Check that the second store is selected.

The sandbox searches real stores and stops before payment, so no order is placed. Food delivery at a store such as DoorDash asks the shopper to sign in to their own account before checkout, as "Signing in to a store's account" shows.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.