Actions and Factories

Actions

actions is an object provided by event.detail for various player content manipulations.

cart

updateProduct

Update product info for a product in cart. Similar to product hydration but may contain products not related to current video since player cart is just a mirror of storefront cart.

updateProductQuantity

Quick way to update cart product quantity without updating the product itself.

configure

Update the cart's checkout CTA link and currency

shopping

hydrateProduct

Action to provide latest product update via hydration.

video

update

Action to allow storefront to update video info like i18n caption , CTA and more..

actions.cart.updateProductQuantity

Accepts an object of variant ext_id and quantity and updates the cart item

actions.cart.updateProductQuantity({ id: 'xyz', quantity: 3 })

actions.cart.configure

Accepts an object of currency and url for the cart (url will be used for checkout CTA); addToCartText and itemInCartText are used to customize the text on the cart related CTAs and they are optional

actions.cart.configure({ currency: 'USD', url: 'https://shop.com/cart', addToCartText: 'Add to Bag', itemInCartText: 'Item in Bag' })

actions.cart.resetCart

Clears the cart content.

actions.shopping.hydrateProduct

Accepts a callback with productFactory as first argument param expecting a product to be returned.

actions.shopping.hydrateProduct(({ productFactory }) =>
  productFactory((p) => p.name("Top secret"))
);

WooCommerce product hydration example

/**
 * An example of a product hydration on WooCommerce storefront.
 *
 * Attach the listener to `fw:shopping:hydrate-products` which gets
 * fired with each video/livestream containg a product.
 */
document.addEventListener("fw:shopping:hydrate-products", async (event) => {
  /**
   * event.detail contains list of `products`
   * attached to current video along with set of `actions` which
   * can be used to hydrate each individual product
   */
  const { products, actions } = event.detail;

  products.forEach((p) => {
    /**
     * product's `product_ext_id` is the ID identifying
     * current product within store database.
     */
    if (p.product_ext_id) {
      /**
       * Request for the latest product information
       * using your own fetch method `getProductById`
       */
      getProductById(p.product_ext_id).then((wooProduct) => {
        if (wooProduct.id) {
          /**
           * `actions.shopping.hydrateProduct` provides
           * a factory to update (hydrate) the product with the latest info.
           */
          actions.shopping.hydrateProduct(({ productFactory }) =>
            productFactory((p) => {
              /**
               * `productFactory` is a factory function which accepts callback
               * function returning a new product object.
               */
              const product = p
                .description(wooProduct.description)
                .ext_id(wooProduct.id)
                .name(wooProduct.name);

              wooProduct.variations.forEach((wooVariant) => {
                /**
                 * `product.variant` accepts callback which returns
                 * a new variant object. Please note each product needs
                 * at least one variant.
                 */
                product.variant((v) => {
                  const variant = v
                    .ext_id(wooVariant.variation_id)
                    .isAvailable(wooVariant.is_in_stock)
                    .name(wooVariant.sku)
                    .price(wooVariant.display_price)
                    .sku(wooVariant.sku);

                  /*
                   * Modify or add images based on your ext_id.
                   */
                  if (wooVariant.image) {
                    variant.image((i) =>
                      i
                        .ext_id(wooVariant.image_id)
                        .position(0)
                        .title(wooVariant.image.alt)
                        .url(wooVariant.image.src)
                    );
                  }

                  /*
                   * Variant options like "size", "color"
                   * with their corresponding values.
                   */
                  Object.entries(wooVariant.attributes || {}).forEach(
                    ([name, value]) =>
                      variant.option({
                        name: name.replace(/attribute_/, ""),
                        value,
                      })
                  );

                  return variant;
                });
              });

              return product;
            })
          );
        } else {
          console.warn(`Cant fetch product by ext_id "${p.product_ext_id}"`);
        }
      });
    }
  });
});

Factories

Product factory

Product factory is a function provided by a product hydration event which expects callback returning new product with associated variants and images. Each factory method returns self so calls can be chained.

productFactory(product => product)

NameDescriptionRequired

ext_id

External ID. Identifier in a partner database. Value is used to match and update products synced with Firework using various e-commerce integration tools.

Yes

name

Product name

Yes

description

Product description. Markdown for rich formating is allowed.

Yes

currency

Currency code. e.g. "USD"

Yes

variant

Variant factory, see below.

Yes

// Example of product hydration using product factory.

actions.shopping.hydrateProduct(({ productFactory }) =>
  productFactory((product) => {
      return product.ext_id("1").name("First Product");
  })
);

Variant factory

Variant factory used to feed product with multiple variants (e.g. different size or colors). Please note each product needs at least one variant.

NameDescriptionRequired

ext_id

External ID. Variant identifier in a partner database. Value is used to match and update variants synced with Firework using various e-commerce integration tools.

Yes (If this is only created to satisfy product requirement where every product needs a variant, this can be the same as product's ext_id )

sku

SKU identifier.

Optional

name

Variant name.

Optional

url

URL to product/variant detail page.

Yes

price

Numeric value of current price

Yes

originalPrice

Numeric value of original price

Optional

isAvailable

Boolean indicating whether variant is currently available (out of stock).

Optional

image

Image factory, see below.

Optional

option

Accepts {name, value} object with variant option.

Optional

position

Numeric position amongst other variants. Variant options will also be sorted by this position.

Optional

// Example of providing multiple variants.

actions.shopping.hydrateProduct(({ productFactory }) =>
  productFactory((product) => {
    return product
      .ext_id("123")
      .name("T-Shirt")
      .variant((variant) => {
        return variant
          .ext_id("123redxl")
          .name("Red XL")
          .price(10.0)
          .originalPrice(20)
          .option({
            name: "Color",
            value: "Red"
          })
          .option({
            name: "Size",
            value: "XL"
          });
      })
      .variant((variant) => {
        return variant
          .ext_id("123bluexl")
          .name("Blue XL")
          .price(10.0)
          .option({
            name: "Color",
            value: "Blue"
          })
          .option({
            name: "Size",
            value: "XL"
          });
      });
  })
);

Image factory

Image factory to provide product (or variant) images.

NameDescriptionRequired

ext_id

External ID of an image in partner database used to match images between partner and Firework database.

Yes

title

Alt title for an image.

Optional

position

Numeric value used to sort multiple images.

Optional

url

URL location of an image.

Yes

// Example of providing multiple images to the variant.

actions.shopping.hydrateProduct(({ productFactory }) =>
  productFactory((product) => {
    return product
      .ext_id("123")
      .name("T-Shirt")
      .variant((variant) => {
        return variant
          .ext_id("123blue")
          .name("Blue XL")
          .price(10.0)
          .option({
            name: "Color",
            value: "Blue"
          })
          .option({
            name: "Size",
            value: "XL"
          })
          .image((image) => {
            return image
              .ext_id("img1")
              .position(1)
              .title("T-Short, Blue, XL, front view")
              .url("https://example.com/image.jpg");
          })
          .image((image) => {
            return image
              .ext_id("img2")
              .position(2)
              .title("T-Short, Blue, XL, back view")
              .url("https://example.com/another-image.jpg");
          });
      });
  })
);

Last updated