How to - Add to favorites / wishlist

In Tweakwise JS, an add-to-favorites button can be added to the product tile. This button will not automagically add the product to the wishlist: Tweakwise JS will trigger an event which can be used to implement this behavior.

Plugin Studio

Add a Button element to your tile, for example put a heart emoji as text or use an SVG as icon:

Next, configure the Add to favorites event on the element, using the Click event panel:

A click/tap on this button will result in the twn.add-to-favorites event in the event hooks.

Notes:

  • If you want to use an SVG icon, convert the svg to base64 and use it in the stylesheet.

State

Part of properly implementing a favorites button is keeping track of what your users liked. In the previous code snippet you have hooked up your service to add a product to the wishlist for a particular user and now it is time to reflect this state in the appearance of the button every time a lister page is loaded.

Follow these steps to show the correct state on a product tile:

  • Get the active wishlist contents
  • Find the corresponding product tile (if available)
  • Add an active state to the product, e.g. add a is-favorite class
  • In Studio, make sure the tile adapts to the active state, for example show/hide respective icons corresponding to the state.

Function to set the state of products on the wishlist

function tw__applyWishlist(products){
  // fetch product IDs added to the wishlist.
  // either inject serverside or clientside.
  var addedProducts = ...
  for (var product of products) {
    // Check if added to a wishlist
    if (!addedProducts.includes(product.itemno)) return;
    var element = document.querySelector('[data-item-id="' + product.itemno + '"]');
    if (!element) return;
     element.classList.add('is-favorite');
  } 
}

Set state on loading

Search and merchandising

const listerPage = tweakwiseListerPage({
  // ... other options ...
  on: {
    // ... other eventhandlers ...
    "twn.request.success": function (event) {
      // apply to search results
      tw__applyWishlist(event.data.groups || event.data.items);
    },
    "twn.request.navigation.success": function (event) {
		// apply to merchandising results
      tw__applyWishlist(event.data.groups || event.data.items);
    }
  }
});
<script>
  window["twn-starter-config"] = {
    // ... other options ...
    on: {
      // ... other eventhandlers ...
      "twn.request.success": function (event) {
				// apply to search results
        tw__applyWishlist(event.data.groups || event.data.items);
      },
      "twn.request.navigation.success": function (event) {
				// apply to merchandising results
        tw__applyWishlist(event.data.groups || event.data.items);
      }
    }
  };
</script>

Suggestions

tweakwiseSuggestions({
  // ... other options ...
  on: {
    // ... other eventhandlers ...
    "twn.request.success": function (event) {
      // apply to search results
      tw__applyWishlist(event.data.groups || event.data.items);
    }
  }
});

Recommendations

tweakwiseRecommendations({
// ... other options ...
  on: {
    // ... other eventhandlers ...
    "twn.request.success": function (event) {
      // apply to search results
      tw__applyWishlist(event.data.groups || event.data.items);
    }
  }
});

Guided selling

tweakwiseGuidedSelling({
  // ... other options ...
  on: {
    // ... other eventhandlers ...
    "twn.request.success": function (event) {
      // apply to search results
      tw__applyWishlist(event.data.groups || event.data.items);
    }
  }
});

Adding or removing products

Use the twn.add-to-favorites hook to actually add the product to your wishlist/favorites.

Search and merchandising

  window["twn-starter-config"] = window["twn-starter-config"] || {};
  window["twn-starter-config"].on = {
    // ...
    "twn.add-to-favorites": function (event) {
      var productId = event.data.itemno;

      // use productId to add (or remove) the product to the wishlist
			// e.g. use a (fictional) wishlist endpoint
			fetch('/wishlist/add', { method: 'POST', body: JSON.stringify({ id: productId }) });
      
			//Change the state of the button on your product tile
			var element = document.querySelector('[data-item-id="' + product.itemno + '"]');
      if (!element) return;

      element.classList.add('is-favorite'); // or  element.classList.remove('is-favorite');
    }
  };
tweakwiseListerpage({
	// ... other options ...
	on: {
    // ... other event handlers ...
    "twn.add-to-favorites": function (event) {
      var productId = event.data.itemno;

      // use productId to add (or remove) the product to the wishlist
			// THIS IS A CALL TO A FICTIONAL ENDPOINT, REPLACE IT WITH YOUR OWN
			fetch('/wishlist/add', { method: 'POST', body: JSON.stringify({ id: productId }) });
      
			//Change the state of the button on your product tile
			var element = document.querySelector('[data-item-id="' + product.itemno + '"]');
      if (!element) return;

      element.classList.add('is-favorite'); // or  element.classList.remove('is-favorite');
    }
  };
});

Suggestions

tweakwiseSuggestions({
  // ... other options ...
  on: {
    // ... other event handlers ...
    "twn.add-to-favorites": function (event) {
      var productId = event.data.itemno;

      // use productId to add (or remove) the product to the wishlist
			// THIS IS A CALL TO A FICTIONAL ENDPOINT, REPLACE IT WITH YOUR OWN
			fetch('/wishlist/add', { method: 'POST', body: JSON.stringify({ id: productId }) });
      
			//Change the state of the button on your product tile
			var element = document.querySelector('[data-item-id="' + product.itemno + '"]');
      if (!element) return;

      element.classList.add('is-favorite'); // or  element.classList.remove('is-favorite');
    }
  }
});

Recommendations

tweakwiseRecommendations({
// ... other options ...
  on: {
    // ... other event handlers ...
    "twn.add-to-favorites": function (event) {
      var productId = event.data.itemno;

      // use productId to add (or remove) the product to the wishlist
			// THIS IS A CALL TO A FICTIONAL ENDPOINT, REPLACE IT WITH YOUR OWN
			fetch('/wishlist/add', { method: 'POST', body: JSON.stringify({ id: productId }) });
      
			//Change the state of the button on your product tile
			var element = document.querySelector('[data-item-id="' + product.itemno + '"]');
      if (!element) return;

      element.classList.add('is-favorite'); // or  element.classList.remove('is-favorite');
    }
  }
});

Guided selling

tweakwiseGuidedSelling({
  // ... other options ...
  on: {
    // ... other event handlers ...
    "twn.add-to-favorites": function (event) {
      var productId = event.data.itemno;

      // use productId to add (or remove) the product to the wishlist
			// THIS IS A CALL TO A FICTIONAL ENDPOINT, REPLACE IT WITH YOUR OWN
			fetch('/wishlist/add', { method: 'POST', body: JSON.stringify({ id: productId }) });
      
			//Change the state of the button on your product tile
			var element = document.querySelector('[data-item-id="' + product.itemno + '"]');
      if (!element) return;

      element.classList.add('is-favorite'); // or  element.classList.remove('is-favorite');
    }
  }
});

❗️

Notes

  • the snippet is an inspirational example and will differ depending on your wishlist implementation.
  • the snippet is an example on how to overwrite Tweakwise JS configuration in your frontend. If you have more event hooks, make sure all existing are still working correctly.


Did this page help you?