# Inside the admin

> Your app's home, panels beside a record, actions in a record's Apps menu, and actions on the rows a merchant ticks in a list.

Source: https://storeware.ai/docs/extensions/admin

An app shows up in the admin in four ways. Each one is a page of yours that the admin frames, hands a [session](https://storeware.ai/docs/build-apps/installs-and-tokens) to, and talks to over [App Bridge](https://storeware.ai/docs/extensions/app-bridge).

| Kind               | Where it appears                                                                          | Declared with                                            |
| ------------------ | ----------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| Home               | A full height page at `/stores/<id>/apps/<slug>`, with your navigation as tabs above it   | `[app] url` and `[[app.navigation]]`                     |
| Panel              | Beside a record, in the column on the right                                               | `[[extensions.admin]]` at a `.sidebar` or `.block` point |
| Action on a record | In the record's **Apps** menu, opening your page in a window                              | `[[extensions.admin]]` at a `.detail.action` point       |
| Action on a list   | In the list's bar once rows are ticked, opening your page in a window with the ticked ids | `[[extensions.admin]]` at an `.index.action` point       |

## Your home

With `[app] url` set, an installed app gets a full height page in the admin at `/stores/<id>/apps/<slug>`. The admin frames your URL with `?session=<token>`; verify it with `authenticateAdmin` before rendering anything. The path after your slug is the path inside your home, so pages can be bookmarked and back and forward work.

`[[app.navigation]]` entries become tabs above your home, so merchants can reach your pages directly. Your home is the page the [title bar](https://storeware.ai/docs/extensions/app-bridge#title-bar) and the [save bar](https://storeware.ai/docs/extensions/app-bridge#save-bar) are made for, and the page a [modal](https://storeware.ai/docs/extensions/app-bridge#modals) opens a page of.

## Points

Each `[[extensions.admin]]` entry names a point, the URL framed there, and a title: the panel's heading, or the action's name in the menu.

```toml
[[extensions.admin]]
point = "admin.order.detail.sidebar"
url = "https://reviews.example.com/embed/order"
title = "Reviews"

[[extensions.admin]]
point = "admin.product.index.action"
url = "https://reviews.example.com/embed/ask-for-reviews"
title = "Ask for reviews"
```

| Point                             | What it is                                                       | In `context`                       |
| --------------------------------- | ---------------------------------------------------------------- | ---------------------------------- |
| `admin.product.detail.sidebar`    | A panel beside a product                                         | `productId`, `productHandle`       |
| `admin.product.detail.action`     | An action in a product's Apps menu                               | `productId`, `productHandle`       |
| `admin.product.index.action`      | An action on the products ticked in the list                     | `selection`                        |
| `admin.collection.detail.sidebar` | A panel beside a collection                                      | `collectionId`, `collectionHandle` |
| `admin.collection.detail.action`  | An action in a collection's Apps menu                            | `collectionId`, `collectionHandle` |
| `admin.order.detail.sidebar`      | A panel beside an order                                          | `orderId`, `orderNumber`           |
| `admin.order.detail.action`       | An action in an order's Apps menu                                | `orderId`, `orderNumber`           |
| `admin.orders.index.action`       | An action on the orders ticked in the list                       | `selection`                        |
| `admin.customer.detail.sidebar`   | A panel beside a customer                                        | `customerId`                       |
| `admin.customer.detail.action`    | An action in a customer's Apps menu                              | `customerId`                       |
| `admin.customers.index.action`    | An action on the customers ticked in the list                    | `selection`                        |
| `admin.settings.block`            | A block at the foot of the shop's settings, sharing its save bar | nothing                            |

`context` is in the session's claims, and in App Bridge's welcome. Every point reads the release the shop has approved: a panel added or moved by a newer manifest appears once the merchant approves that release.

## Actions on a list

An action at an `.index.action` point appears in the list's bar once a merchant ticks rows. Choosing it opens your page in a window over the list, and `context.selection` holds the ids of the rows ticked, at most 100.

The selection is inside the signed session token, never in your page's address. Nobody can hand your app a selection the merchant did not make by editing a URL, and your server reads it from the claims it has already verified:

```ts
const admin = await storeware.authenticateAdmin(request);
const ids = admin.claims.context.selection ?? [];
```

A list's actions act on the rows ticked on the page. When a merchant chooses every row that matches across pages, the Apps button is off: those rows were never sent to the browser.

When your action is done, close the window with `modal.close` from [App Bridge](https://storeware.ai/docs/extensions/app-bridge#modals). The merchant can always close it themselves.

## Actions on a record

An action at a `.detail.action` point is listed in the record's **Apps** menu, at the top of the page, with your app's name beside it. It opens your page in a window with the record's id in `context`, and closes the same way.

## The frame

- Your page is cross origin and sandboxed: it cannot reach the admin's cookies or page.
- Every panel and window is labelled with your app's name, so a merchant can always tell your page from Storeware's.
- Talk to the admin with `postMessage` to its exact origin, never `*`, and check the origin of everything you receive. [App Bridge](https://storeware.ai/docs/extensions/app-bridge) does both.
- Send your session token on calls to your own server, rather than setting cookies, which a framed page may not keep.
- A panel's height follows what you ask for, between 80 and 1200 pixels.
