Skip to content
Twilight React Playground
ثيم رائدaren

wishlist

objectBeginnerserverbrowserlive demo

Lists the products the signed-in customer saved, one numbered page at a time; saving and unsaving stay with the Salla SDK.

import { wishlist, WishlistListParams } from '@salla.sa/twilight-theme-engine/api/wishlist';

In plain words

Shoppers save products they like to a wishlist. wishlist.list({ page }) returns those saved products, a page at a time, as ordinary product objects you can draw with a product card.

It only reads. Saving and unsaving go through the Salla SDK, or the useWishlist hook, which also tells you whether one product is saved.

Signature

wishlist.list(params?: WishlistListParams): Promise<ProductsListResult>   // { items, next }
wishlist.queries.list(params: Omit<WishlistListParams, 'signal'>)
  // key ['wishlist', 'list', params, { scope }]

interface WishlistListParams {
  page?: number;          // default 1
  perPage?: number;       // default 15
  filterable?: boolean;
  signal?: AbortSignal;
}

Try it live

The signed-in customer's saved products, one numbered page at a time. As a guest you see the disabled query.Try this: change the page and watch the key: the page and the active branch scope are both part of it.
Storefront canvas · en · LTR
Runs in the browser…
Controls
What a theme writes
import { useQuery } from '@tanstack/react-query';
import { getAuthToken } from '@salla.sa/twilight-theme-engine/api/client';
import { wishlist } from '@salla.sa/twilight-theme-engine/api/wishlist';

export function SavedProducts() {
  const { data } = useQuery({
    ...wishlist.queries.list({ page: 1 }),
    enabled: Boolean(getAuthToken()),
  });

  return (
    <ul>
      {data?.items.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

Example

app/components/account/WishlistGrid.tsx
import { useQuery } from '@tanstack/react-query';
import { getAuthToken } from '@salla.sa/twilight-theme-engine/api/client';
import { wishlist } from '@salla.sa/twilight-theme-engine/api/wishlist';
import { ProductCard } from '@salla.sa/twilight-theme-engine/components/product';

export function WishlistGrid({ page }: { page: number }) {
  const { data } = useQuery({
    ...wishlist.queries.list({ page }),
    enabled: Boolean(getAuthToken()),
  });

  return (
    <div className="s-products-list-wrapper s-products-list-vertical-cards">
      {data?.items.map((item, index) => (
        <ProductCard key={item.id} product={item} index={index} />
      ))}
    </div>
  );
}

How it behaves

  • Endpoint: GET products?source=wishlist&page=…&per_page=…, plus filterable when given. It is kept apart from product.list so page numbers and cursors never mix.

  • A guest gets HTTP 401 unauthorized (demo store). The engine wishlist loader wraps the call in orUnauthorized, which does handle that 401.

  • Like product.list, every item is remembered as a list-card preview, and the key includes the active branch scope.

Gotchas

  • filterable: true is sent, but the result has only items and next: the response filters are dropped.

  • Paginate with page. next comes back too, but WishlistListParams has no cursor to send it to.

  • The saved list does not follow the SDK: after useWishlist().toggle() or Salla.wishlist changes, invalidate ['wishlist', 'list'] to read it again.

Related

Source and docs