docs

Promotions

Overview

The Promotion feature allows you to offer discounts and special deals to customers based on predefined conditions. Promotions are designed to enhance user engagement, increase conversion rates, and encourage higher average order values by automatically applying discounts or offering free gifts when certain criteria are met.

Promotions are integrated throughout the SCAYLE Storefront experience—including the Product Listing Page (PLP), Product Detail Page (PDP), Basket, and Order Summary—ensuring users are continuously informed about active deals.

For more information on promotion types and how to configure them, refer to our Promotion Guidelines.

Key Features

  • Automatic application of eligible promotions based on user actions.
  • Flexible condition setup based on product quantity, total order value, or specific product combinations and attributes.
  • Promotion prioritization logic ensures the most relevant offer is shown.
  • Built-in UI components like badges, ribbons, and banners to clearly communicate promotional deals.
  • Full support for configuration via the SCAYLE Panel or API, empowering both developers and marketing teams to align promotions with business goals.

Promotions API

Promotions are managed via the SCAYLE Promotions API. They can be created or updated through:

For technical details and payload structure, refer to the Developer Guide or contact your SCAYLE representative.

Promotion Custom Data

Each promotion can include a customData object within its payload, allowing fine-grained customization. This object supports advanced UI configurations, such as custom colors, headlines, sublines, condition descriptions, and links. You can read more about customData fields and their usage in our Configuration Guideline.

If customData is not set, default UI behavior ensures promotions are still fully functional, maintaining a consistent fallback display.

Here’s the expected TypeScript declaration:

declare module '@scayle/storefront-nuxt' {
  interface PromotionCustomData {
    product?: {
      attributeId: number
      badgeLabel: string
    }
    headline?: string
    subline?: string
    conditions?: string
    minimumOrderValue?: number
    color?: {
      background: string
      text: string
    }
    hideCountdown?: boolean
    link?: string
  }
}

This is a compile-time check only! If the actual API data differs from the declared type, features may break and will require updates across multiple implementation points.

Color

You can customize the appearance of a promotion by setting color values in customData.color. This object supports two properties: background and text, which define the background color and text color of the promotion, respectively.

If no color values are provided, the system will fall back to the default colors defined in ~/utils/promotion.ts under the constant FALLBACK_PROMOTION_COLORS.

You can make the Promotions clickable if you set the link value in customData.link. The value of the link should be a relative path.

Conditions

By default, SFProductPromotionBanner only displays the promotion condition within the promotion list modal. To show the condition in other contexts where the component is used, you can set the showCondition property to true.

Linking Promotions to Products

To connect a promotion to a product, both must share a common identifier—promotion attributeId. You can learn how to configure this attributeId in the Configuration Guideline.

Once the promotion attribute is enabled on the product, you can retrieve the ID like this:

const productPromotionId = getFirstAttributeValue(product.attributes, 'promotion')?.id;

This ID must match promotion.customData.product.attributeId. If the promotion attribute is missing from a product, the promotion components won’t appear on PLP or PDP—but will still be displayed in the Basket, as basket items always include promotion data.

Data Handling

Important Considerations

  • Single Promotion Per Item: Only one promotion can be applied to a product at a time. The promotion with the highest priority (lowest numerical value) will be used.
  • Item-Level Promotions: SCAYLE currently does not support order-level promotions. All discounts are applied at the item level.

Basket flow

Whenever a basket updates, for instance when items are added, removed, or updated in the basket, or when a user logs in, promotions are not auutomatically applied. After the update was successfully performed promotions can be applied using the useApplyPromotions composable.

//...
const { applyPromotions } = useApplyPromotions()
const basket = useBasket()
const { removeItemByKey, addItem: addItemToBasket, updateItem } = basket
//...
const addItem = async (item: AddToBasketItem) => {
   //...
   await addItemToBasket({ ...item, existingItemHandling })
   await applyPromotions(basket.data)
   //...
}

//...

Internaly useApplyPromotions will take the first promotion from basket.applicablePromotions with an itemId and applies it to the first basket item without promotion and the basketItem.key matching the itemId. After applying a promotion, the process repeats with updated basket data until no more promotion can be applied.

Buy X, Get Y promotions within applicablePromotions do not have an itemId set. Therefore, when adding the "Y"-Item to the basket you need to manually set the promotionId.

Promotion Types

There are two main types of promotions:

  • Automatic Discount: The discount applies when certain conditions are met, such as a minimum order value or a required quantity of the same product.
  • Buy X, Get Y: A customer can receive a free product when purchasing a specified number of items or reaching a minimum spend threshold.

Promotion Components

Promotions are communicated via dedicated components across the user journey. These components have fallback designs when no customData is provided.

Promotion Overview (Deals Flyout)

Located under the “Deals” navigation icon, this flyout shows all active promotions. Each promotion is displayed as a card with:

  • Promotion name
  • Countdown timer
  • Optional progress bar for MOV (Minimum Order Value)
  • Conditions
  • Link to eligible products

To show the MOV progress bar, set promotion.customData.minimumOrderValue and ensure it matches the configured conditions.

If no promotions are active, users are informed they can check again later.\

Flyout With Active Promotions & Flyout Without Active Promotions

Behavior

  • Default (No customData):
    • Displays active promotions in a flyout
    • Uses default promotion colors
    • Includes only the promotion name
  • Enhanced (With customData):
    • Uses custom colors from customData.color.background and customData.color.text
    • Displays a custom message using customData.headline and customData.subline
    • Makes the card clickable using the link in customData.link

Promotion Ribbon

Displayed globally across all pages (except checkout). The highest-priority promotion is selected based on the priority flag in the promotion payload. The promotion that has the lowest priority value has the highest priority. If two promotions have the same highest priority, the first promotion from the list will be selected to be displayed in the ribbon.

Behavior

  • Default (No customData):
    • Uses default color and text styling
    • Includes only the promotion name
  • Enhanced (With customData):
    • Displays a custom message using customData.headline and customData.subline
    • Makes the ribbon clickable using the link in customData.link

Promotion Ribbon With customData

Promotion Banner

The promotion banner appears on PDPs, and, for MOV promotions, in the Basket.

On PDP, the banner is shown only if the promotion’s customData.product.attributeId matches the promotion attribute present on the product.

On the Basket page, only the MOV promotion banner is displayed. It appears above the product list and provides real-time feedback on how close the user is to unlocking the promotion.

While similar in appearance to the promotion overview card, the banner does not include full promotion conditions. For MOV-based promotions, the banner displays:

  • MOV not reached: Shows the remaining amount needed to unlock the promotion.\

    MOV Not Reached

  • MOV reached but no eligible product in the cart: Informs users they need to add a promotion product.\

    MOV Reached But No Eligible Product In The Cart

  • MOV reached and eligible product in the cart: Displays the savings achieved.\

    MOV Reached And Eligible Product In The Cart

To enable the MOV progress bar inside the banner for automatic discount promotions, the minimumOrderValue field must be provided inside promotion.customData. This value must be aligned with the actual promotion conditions configured via the creation or update payload.

Behavior

  • Default (No customData):
    • Uses default promotion colors.
    • Displays a promotion name.
  • Enhanced (With customData):
    • Uses custom colors from customData.color.background and customData.color.text
    • Displays a custom message using customData.headline and customData.subline
    • Makes the banner clickable using the link in customData.link

Banner (MOV) With customData

Promotion Badge

The promotion badge is a small visual label displayed on product cards to indicate an ongoing promotion. It is shown on PLPs and Basket product cards. The badge is only displayed if a product is linked to a promotion by attributeId and the same Id is added to the customData.

Behavior

  • Default Badge (No customData)
    • Uses default promotion colors.
    • Displays a generic promotion label.
  • Custom Badge (With customData)
    • Uses colors from customData.color.background and customData.color.text.
    • Displays a custom label from customData.product.badgeLabel, provided that customData.product.attributeId is present and valid.

Badge With A customData (Top) And Without (Bottom)

Promotion Discount

Promotion discounts are shown alongside price details to reflect the savings users receive from an active promotion. These appear on both the PDP and in the Basket.

  • On PDP: The discount is shown only if the product’s attributeId in customData.product matches the product's promotion attribute. Once a variant is added to the basket, the discount will be recalculated based on basket data.
  • On Basket: The discount is always shown, including:
    • The original (crossed-out) price
    • The discounted amount

Behavior

  • Default Discount (No customData) → Uses standard promotion colors.
  • Custom Discount (With customData) → Uses custom colors (customData.color.background, customData.color.text).

Promotion Price Summary

The Promotion Price Summary is located in the Basket's price breakdown area and shows the total savings from all active promotions.

The summary uses an accordion layout:

  • In its collapsed state, it shows the overall amount saved.
  • When expanded, it breaks down savings by individual promotions.

Behavior

  • Default Display (No customData)
    • Uses default promotion color.
    • Displays the promotion name.
  • Custom Display (With customData)
    • Uses customData.color.background and customData.color.text.
    • Displays customData.headline.

Promotion Price Summary With customData

Gift Collection

The Gift Collection component is used exclusively for Buy X, Get Y promotion types. It showcases eligible gift items and is shown on both the PDP and the Basket.

  • On PDP: The collection is visible only if the selected product has a matching attributeId and the promotion conditions are met. This typically occurs after a qualifying product variant has been added to the basket.
  • On Basket: The collection appears above the product list. If a user adds a gift product while all promotion conditions are satisfied:
    • The product is labeled as "free"
    • A discount is applied automatically

If a qualifying promotion product is removed from the basket, the gift product will convert into a regular, paid item.

Behavior

  • Default Display (No customData)
    • Uses default promotion color.
  • Custom Display (With customData)
    • Uses customData.color.background and customData.color.text.

Gift Collection On The Basket Page

Sold-Out Variants of Free Products

Sold-out variants remain visible on the PDP and basket to ensure users are informed of all available options.

  • These variants are not filtered out or hidden.
  • If all variants of a product are sold out, the product is labeled as “sold-out.

Configuring Your Promotions

To explore all available options for configuring your promotions—including setup steps, custom data fields, and product linking—please refer to our Promotion Configuration Guide.