# Account slots (https://docs.salla.dev/twilight/react/slots/account)



Use account slots when you want to add a banner, a loyalty block or a custom section to the profile, orders, wallet, wishlist or notifications pages without replacing them. For how `useHook`, priority, fallback and cleanup work, see [Slots](https://docs.salla.dev/twilight/react/slots) and [Page frame slots](https://docs.salla.dev/twilight/react/slots/page-frame).

All account pages render inside [`CustomerLayout`](https://docs.salla.dev/twilight/react/layouts/customer-layout), so the account menu and page title come from the layout and sit outside every slot below.

<Callout title="Framework: TanStack Start">
  These slots are rendered by the engine's TanStack Start routes.
</Callout>

## Context [#context]

None of the account slots pass their own context. Every handler receives only `twilight` (store, theme and more). Read order, wallet or wishlist data from your own hooks or loaders, not from the slot.

## Profile [#profile]

Route: [Profile](https://docs.salla.dev/twilight/react/routes/account-profile).

<PageLayout
  title="Profile"
  url="/account/profile"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:profile.start' },
      { slot: 'customer:profile.form.start' },
      { block: 'Profile form', size: 'lg' },
      { slot: 'customer:profile.form.end' },
      { block: 'Verification', size: 'sm' },
      { block: 'Notification settings', size: 'sm' },
      { slot: 'customer:profile.end' },
    ] },
  ] },
]"
/>

| Slot                          | Position                                                       | Context    | Notes            |
| ----------------------------- | -------------------------------------------------------------- | ---------- | ---------------- |
| `customer:profile.start`      | First thing on the page, above the form.                       | `twilight` | Always rendered. |
| `customer:profile.form.start` | Directly above the profile form.                               | `twilight` | Always rendered. |
| `customer:profile.form.end`   | Directly below the profile form, above the verification block. | `twilight` | Always rendered. |
| `customer:profile.end`        | Last thing on the page, below the notification settings.       | `twilight` | Always rendered. |

## Settings [#settings]

Route: [Settings](https://docs.salla.dev/twilight/react/routes/account-settings).

<PageLayout
  title="Settings"
  url="/account/settings"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:settings.start' },
      { block: 'User settings', size: 'lg' },
      { slot: 'customer:settings.end' },
    ] },
  ] },
]"
/>

| Slot                      | Position                      | Context    | Notes            |
| ------------------------- | ----------------------------- | ---------- | ---------------- |
| `customer:settings.start` | Above the settings component. | `twilight` | Always rendered. |
| `customer:settings.end`   | Below the settings component. | `twilight` | Always rendered. |

The profile page also shows the user settings component, but it does not render the `customer:settings.*` slots. Use the profile slots there.

## Notifications [#notifications]

Route: [Notifications](https://docs.salla.dev/twilight/react/routes/account-notifications).

<PageLayout
  title="Notifications"
  url="/account/notifications"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:notifications.items.start', note: 'also when empty' },
      { block: 'Notification list or empty state', size: 'lg' },
      { slot: 'customer:notifications.items.end', note: 'also when empty' },
    ] },
  ] },
]"
/>

| Slot                                 | Position                     | Context    | Notes                                          |
| ------------------------------------ | ---------------------------- | ---------- | ---------------------------------------------- |
| `customer:notifications.items.start` | Above the notification list. | `twilight` | Rendered even when there are no notifications. |
| `customer:notifications.items.end`   | Below the notification list. | `twilight` | Rendered even when there are no notifications. |

## Orders list [#orders-list]

Route: [Orders](https://docs.salla.dev/twilight/react/routes/account-orders).

<PageLayout
  title="Orders list"
  url="/account/orders"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:orders.index.items.start' },
      { block: 'Status filters', size: 'xs' },
      { block: 'Orders table or empty state', size: 'lg' },
      { slot: 'customer:orders.index.items.end' },
    ] },
  ] },
]"
/>

| Slot                                | Position                                | Context    | Notes                                          |
| ----------------------------------- | --------------------------------------- | ---------- | ---------------------------------------------- |
| `customer:orders.index.items.start` | Above the status filters and the table. | `twilight` | Rendered even when the customer has no orders. |
| `customer:orders.index.items.end`   | Below the table (or the empty state).   | `twilight` | Rendered even when the customer has no orders. |

## Single order [#single-order]

Route: [Order](https://docs.salla.dev/twilight/react/routes/account-order).

<PageLayout
  title="Single order"
  url="/account/orders/123"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:orders.single.details.start' },
      { block: 'Gift tag and edit order button', size: 'xs' },
      { block: 'Order details, items and totals', size: 'xl' },
      { slot: 'customer:orders.single.details.end' },
      { block: 'Rating and reorder modals', size: 'xs' },
    ] },
  ] },
]"
/>

| Slot                                   | Position                                                                                        | Context    | Notes                                            |
| -------------------------------------- | ----------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------ |
| `customer:orders.single.details.start` | First thing in the order content, above the gift tag and the order details table.               | `twilight` | Always rendered.                                 |
| `customer:orders.single.details.end`   | After the last order section (details, shipping, payment and rating blocks), before the modals. | `twilight` | Always rendered. Modals render outside the slot. |

## Wallet [#wallet]

Route: [Wallet](https://docs.salla.dev/twilight/react/routes/account-wallet).

With transactions:

<PageLayout
  title="Wallet with transactions"
  url="/account/wallet"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:wallet.transactions.start' },
      { block: 'Balance card', size: 'sm' },
      { block: 'Transactions table', size: 'lg' },
      { slot: 'customer:wallet.transactions.end' },
    ] },
  ] },
]"
/>

With no transactions:

<PageLayout
  title="Wallet, empty"
  url="/account/wallet"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:wallet.transactions.start' },
      { block: 'Empty state', size: 'md' },
      { slot: 'customer:wallet.transactions.end' },
    ] },
  ] },
]"
/>

| Slot                                 | Position                                                            | Context    | Notes            |
| ------------------------------------ | ------------------------------------------------------------------- | ---------- | ---------------- |
| `customer:wallet.transactions.start` | Top of the page, above the balance card (or above the empty state). | `twilight` | Always rendered. |
| `customer:wallet.transactions.end`   | Below the transactions table (or below the empty state).            | `twilight` | Always rendered. |

<Callout>
  The wallet page renders each slot in two places because it has two layouts: the empty state when the customer has no transactions, and the balance plus table otherwise. Exactly one of them is on screen, so a handler never shows twice. The empty state has no balance card.
</Callout>

## Wishlist [#wishlist]

Route: [Wishlist](https://docs.salla.dev/twilight/react/routes/account-wishlist).

<PageLayout
  title="Wishlist"
  url="/account/wishlist"
  nodes="[
  { cols: [
    { w: 1, nodes: [{ block: 'Account menu', size: 'lg' }] },
    { w: 3, nodes: [
      { slot: 'customer:wishlist.items.start' },
      { block: 'Share bar', size: 'xs' },
      { block: 'Product list or empty state', grid: 3 },
      { slot: 'customer:wishlist.items.end' },
    ] },
  ] },
]"
/>

| Slot                            | Position                                  | Context    | Notes                                     |
| ------------------------------- | ----------------------------------------- | ---------- | ----------------------------------------- |
| `customer:wishlist.items.start` | Above the share bar and the product list. | `twilight` | Rendered even when the wishlist is empty. |
| `customer:wishlist.items.end`   | Below the product list (or empty state).  | `twilight` | Rendered even when the wishlist is empty. |

## Example [#example]

Show a banner above the customer's orders. Render the component once under your layout, as described in [`useHook`](https://docs.salla.dev/twilight/react/hooks/use-hook).

```tsx title="app/components/account/OrdersBanner.tsx"
import { useHook } from '@salla.sa/twilight-theme-engine/hooks/useHook';

export function OrdersBanner() {
  useHook('customer:orders.index.items.start', () => (
    <p className="mb-4 rounded bg-yellow-50 p-3 text-sm">
      Need help with an order? Contact support and quote the order number.
    </p>
  ));
  return null;
}
```

The banner also shows when the customer has no orders, because the slot sits above the empty state.

## Next [#next]

* [Slots](https://docs.salla.dev/twilight/react/slots) explains how registration, priority and fallback work.
* [`useHook`](https://docs.salla.dev/twilight/react/hooks/use-hook) is the API used above.
* [Blog slots](https://docs.salla.dev/twilight/react/slots/blog) covers the blog pages.
