UI Extension — Recipes

Custom API

By specifying api="custom" , you can override the data fetching behavior. In the following example, you can combine the results from two different Miso APIs (code example):

const model = new MisoClient.ui.models.classes.MisoListModel({
  api: 'custom',
  fetch: fetch

async function fetch({ payload, client }) {
  // call both API in bulk mode, so they are combined into a single request
  const [ response0, response1 ] = await Promise.all([
    client.api.recommendation.productToProducts({ product_id: '...', fl: ['*'], rows: 4 }, { bulk: true }),
    client.api.recommendation.userToProducts({ fl: ['*'], rows: 4 }, { bulk: true })
  // combine the retrieved products starting with ones from productToProducts() with list size trimmed to 4
  const products = [...response0.products, ...response1.products].slice(0, 4);
  return {
    products: products,


If you want to deduplicate the results across multiple recommendation sections in one page, you can achieve it using the model’s transform setting (code example).

Given two <miso-list> in the page, each of which shows 4 products:

<miso-list id="x" class="recommendation" auto-model="false" on:start="load">...</miso-list>
<miso-list id="y" class="recommendation" auto-model="false" on:start="load">...</miso-list>

Keep track of shown items and filter out redundant ones:

const shownProductIds = new Set();

function transform(data) {
  // filter out already shown products and trim size to 4
  const items = data.items
    .filter(item => !shownProductIds.has(item.product_group_id))
    .slice(0, 4);
  // keep track of which products are shown
  for (const item of items) {
  return Object.assign({}, data, { items: items });

const MisoListModel = MisoClient.ui.models.classes.MisoListModel;
const misoListX = document.querySelector('#x');
const misoListY = document.querySelector('#x');

misoListX.model = new MisoListModel({
  api: 'user_to_products',
  payload: {
    // ...,
    rows: 8 // in the worst case, 4 of them are filtered out
  transform: transform
misoListY.model = new MisoListModel({
  api: 'product_to_products',
  payload: {
    // ...,
    rows: 8
  transform: transform
Icon/Activity Icon/Add Icon/API Icon/Arrow/Down Icon/Arrow/Left Icon/Arrow/Right Icon/Arrow/TopRight Icon/Arrow/Up Icon/Bento Icon/Billing Icon/Bin Icon/Book Icon/Bookmark/Default Icon/Bookmark/Filled Icon/Calendar Icon/Caret/Down Icon/Caret/Up Icon/Chavron/DownIcon/Chavron/LeftIcon/Chavron/RightIcon/Chavron/UpIcon/Checknox/CheckedIcon/Checknox/Unchecked Icon/Checklist Icon/Chip Icon/Clipboard / Copied Icon/Clipboard/Default Icon/Clock/Stopwatch Icon/CMD Icon/Data/Catalog Icon/Data/Engine Icon/Data/Group Icon/Data/Interact Icon/Data/Users Icon/Dive Icon/Docs/Key Icon/Dojo Icon/Email Icon/Env/Development Icon/Env/Playground Icon/Env/Prod Icon/Folder Icon/Fullscreen/Collapse Icon/Fullscreen/Expand Icon/Guides/Multiple Icon/Guides/Single Icon/Hashtag Icon/Heart/Outline Icon/Heart/Solid Icon / Cart z Icon / Click Icon / Clock Icon / Data Icon / Doc Icon / EmptyCart z Icon/Social/Facebook Icon / Genome Incognito Icon / Money Icon/Social/ProductHunt Icon / Search Icon/Social/Twitter Icon / User Icon/Info/Error Icon/Info/Info Icon/Info/Question Icon/Info/Warning Icon/Interact/Download Icon/Interact/Edit Icon/Interact/External v2 Icon/Interact/External Icon/Interact/Filter Icon/Interact/Logout Icon/Interact/Options Icon/Interact/Re-order Icon/Interact/Reload Icon/Interact/Remove Icon/Interact/Replace Icon/Interact/Search Icon/Interact/Shuffle Icon/Interact/Undo Icon/Interact/Upload Icon/Interact/Video Icon/Invoice Icon/Loading Icon/Loading Icon/Lock/Locked Icon/Lock/Unlocked Icon/Lock Icon/Mapping Menu Icon/Notification Icon/Overview Icon/Person/Team Icon/Person/User Icon/Plan/Enterprise Icon/Plan/Growth Icon/Plan/Startup Icon/Plan/Trial Icon/Recipe Icon/Rocket Icon/Settings/App Icon/Settings/User Icon/Settings Icon/Shrine Icon/Sidebar/Close Icon/Sidebar/Open Icon/Slideout Icon/Sort/Ascending Icon/Sort/Default Icon/Sort/Descending Icon/Star/Filled Icon/Star/Outlined Stopwatch Icon/Support Icon/Tag Icon/Interact/Thumb/Dislike Icon/Interact/Thumb/Like Icon/Tick Icon/Trend/New Icon/Trend/Trending Icon/Tutorial Icon/Lock/Unlocked Icon/View/Grid Icon/View/List Icon/Watchlist/Add