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:
- The SCAYLE Panel
- The API endpoint
/v1/promotions
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
.
Link
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.\
.png)
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
andcustomData.color.text
- Displays a custom message using
customData.headline
andcustomData.subline
- Makes the card clickable using the link in
customData.link
- Uses custom colors from
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
andcustomData.subline
- Makes the ribbon clickable using the link in
customData.link
- Displays a custom message using
.png)
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
andcustomData.color.text
- Displays a custom message using
customData.headline
andcustomData.subline
- Makes the banner clickable using the link in
customData.link
- Uses custom colors from
.png)
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
andcustomData.color.text
. - Displays a custom label from
customData.product.badgeLabel
, provided thatcustomData.product.attributeId
is present and valid.
- Uses colors from
.png)
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
incustomData.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
andcustomData.color.text
. - Displays
customData.headline
.
- Uses
.png)
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
andcustomData.color.text
.
- Uses
.png)
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.