Account orders

The signed-in customer's order history, filterable by status.

Framework: TanStack Start

This page is written for TanStack Start, the default and currently supported framework. See what depends on the framework.

The customer sees their past orders with a status filter and a "load more" list. Customise it to change what the list shows, for example to include each order's items.

URL

URLNotes
/account/ordersall orders
/ar/account/orders?status=pendingwith a language prefix and a status filter
ParamTypeNotes
localestring (optional)ar in the example above
status (search)stringAn order status slug. Empty or missing means all. Any value is sent to the API as is.

Pending orders redirects here with ?status=pending.

Route file

app/routes/account.orders.tsx
// @auto-generated
import { createFileRoute } from '@tanstack/react-router';
import { Orders } from '@salla.sa/twilight-theme-engine/routes/account/orders';
import type { OrdersPageProps } from '@salla.sa/twilight-theme-engine/routes/account/orders';
import { CustomerPageSkeleton } from '@salla.sa/twilight-theme-engine/skeleton';
import { withHead } from '@salla.sa/twilight-theme-engine/tanstack';

export const Route = createFileRoute('/{-$locale}/account/orders')({
  validateSearch: (search: Record<string, unknown>) => {
    const status = (search.status as string) || undefined;
    return status ? { status } : {};
  },
  loaderDeps: ({ search }) => ({ status: search.status }),
  loader: ({ deps, params }): Promise<OrdersPageProps> =>
    Orders.loader({ search: { status: deps.status }, locale: params.locale }),
  head: withHead(Orders),
  pendingComponent: () => <CustomerPageSkeleton />,
  component: OrdersComponent,
});

function OrdersComponent() {
  const data: OrdersPageProps = Route.useLoaderData();
  return <Orders.Component {...data} />;
}

To take the page over, delete the // @auto-generated line and edit the file. See Fork a built-in route.

A customised version

Ask the API to include each order's items (with_items), so a custom component can show product names. Only the loader changes:

app/routes/account.orders.tsx
loader: ({ deps, params }): Promise<OrdersPageProps> =>
  Orders.loader({
    search: { status: deps.status },
    locale: params.locale,
    with_items: true,
  }),

What it loads

OrdersPageProps is { page, orders, cursor, query }. Each order has id, reference_id, status, amounts, currency, created_at, actions (cancellable, reorderable, payable, rateable) and, with with_items, items. The loader calls the orders API with the customer's token. Later pages load in the browser through the returned cursor.

The title is "Orders", or "Pending orders" when ?status=pending. The head also sets the description and language alternates.

Edge cases

  • Signed out or expired token. A guest, or a customer whose token the API rejects with 401 or 403, is sent to the home page with ?intended_to= holding the page they asked for. The Salla SDK opens the sign-in form there and returns them to the page after sign-in.
  • No orders. The page shows a "no orders" message.
  • Filter options. No endpoint lists statuses, so the filter offers "All", the statuses seen on loaded orders, and the selected one.
  • Reloading. The URL has no page number, so a reload starts again at the first page.

See also

On this page