docs
  1. Features
  2. Promotions & Campaigns
  3. Promotion Codes

Promotion Codes

Overview

Promotion Codes provide customers with a way to apply discount offers by entering unique codes during the purchase process. This feature enables targeted marketing, personalized customer incentives, and measurable promotional strategies. Customers can enter codes directly on the basket page, receive immediate feedback on success or failure, and manage multiple codes simultaneously.

This feature is available out of the box starting with Storefront Application v1.11.0 and higher. For more information about this release, see the Storefront Application Changelog.

The Promotion Codes functionality is powered by @scayle/storefront-promotions v2.1.0 and higher. For details about the package and its features, see the @scayle/storefront-promotions Changelog.

Key Capabilities

  • Enter promotion codes through an intuitive input field.
  • Real-time validation and immediate feedback.
  • Support for multiple codes simultaneously.
  • Visual management of applied codes with removal option within the basket.
  • Consistent styling with other promotion UI elements.
  • Integration with the broader promotions & campaigns system.

Additional Information

To learn how to create and configure promotions with code-based activation via the SCAYLE Panel, including generating promotion codes, defining discount effects, and managing code validity, see Setting Up Promotion Codes.

For comprehensive information about the Storefront Application's promotions and campaigns integration, including how deals are displayed across UI components, configuration for different promotion types, and integration with the Promotion Codes feature, see Promotions & Campaigns.

How it works

The Promotion Codes feature is integrated into the Basket page, allowing customers to apply discount codes before proceeding to checkout. It provides a seamless user experience with clear visual feedback and intuitive controls.

Promotion codes are only applied to products in the basket at the time of submitting the respective promotion code. They do not get automatically applied to eligible products added to the basket after the code has already been successfully activated.

User Flow

  1. Code Entry: Customers enter a promotion code in the dedicated input field on the basket page.
  2. Submission: Codes can be submitted by clicking the plus icon button or pressing Enter.
  3. Validation: The system validates the code against available promotions.
  4. Feedback:
    • Success: A success notification appears, the input clears, and the code displays as a chip below the input.
    • Error: An error notification appears and the input clears, prompting the user to try again.
  5. Visual Confirmation: Applied codes appear as styled chips with the promotion's custom colors. A corresponding discount is applied to the products and displayed as a discount badge.
  6. Code Management: Users can remove codes by clicking the X icon on each chip.

Visual Elements

Input Field

The Promotion Codes section includes a headline and an input field with an integrated action button. The input field uses an append-icon slot on the included SFTextInput component to display the plus or minus icon button for code submission or removal.

Promotion Codes in the Basket

Code Chips

Applied promotion codes are displayed as chips below the input field. Each chip includes:

  • The promotion code text (truncated with ellipsis if too long).
  • A remove button (X icon) for removal.
  • Optional custom styling based on the promotion's configuration.

Long codes are truncated and display the full code on hover using the title attribute for accessibility.

Technical Architecture

Promotion Codes are fully integrated into the Storefront Application (starting with v1.11.0 and higher) via the @scayle/storefront-promotions package (starting with v2.1.0 and higher), a Nuxt module that provides composables and utilities for working with promotions.

Component Structure

The Storefront Application includes the SFBasketPromotionCodes.vue component as main integration for Promotion Codes located under components/basket/. It serves as a self-contained component that handles all promotion code functionality via @scayle/storefront-promotions and is intended to be included into the basket summary.

Component Responsibilities

  • Render the promotion code input.
  • Display currently applied promotion codes via chips.
  • Handle code submission and validation.
  • Manage code removal.
  • Provide visual feedback through toast notifications.

Composables

The above component leverages three primary composables from the @scayle/storefront-promotions and @scayle/storefront-nuxt packages:

useApplyPromotions()

Manages applying and removing of promotions from the basket.

Methods:

  • applyPromotions(promotions) - Applies one or more promotions to eligible basket items.
  • removePromotionById(id) - Removes a specific promotion from all basket items where it's applied.

Options:

  • basket (required) - Reference to the current basket that will be updated when promotions are applied or removed.
  • getOrderedPromotions (optional) - Function to customize promotion prioritization (defaults to sorting by priority).

useAppliedPromotionCodes()

Returns a computed map of currently applied promotion codes.

Returns:

A reactive map where keys are promotion codes and values are objects containing:

  • promotion - The full promotion object.
  • itemKeys - Array of basket item keys where this promotion is applied.

useBasket()

Provides access to basket data and methods for interacting with the basket.

Methods:

  • getApplicablePromotionsByCode(code) - Fetches promotions that match the provided code from the basket's applicable promotions.

Data Flow

When a user submits a promotion code via the SFBasketPromotionCodes component, the following steps occur:

  1. Code Submission: User enters a code and submits via button click or Enter key.
  2. Code Lookup: getApplicablePromotionsByCode() queries the basket's applicable promotions for matches.
  3. Promotion Application: Matching promotions are passed to applyPromotions().
  4. Basket Update: The basket is updated via RPC call (updateBasketItem).
  5. UI Update: useAppliedPromotionCodes() reactively updates to reflect the new state.
  6. User Feedback: Toast notification confirms success or reports an error.

Error Handling

The SFBasketPromotionCodes component implements comprehensive error handling:

Error scenarios:

  • Invalid code (code doesn't exist).
  • Code already applied.
  • Code not applicable to current basket items.
  • Network failures during API calls.

In all error cases, the input field is cleared and an error notification is displayed to the user.

Styling and Customization

The Promotion Codes feature maintains visual consistency with other promotion UI elements such as badges on product cards, banners on the PDP and basket, discount indicators, and the deals summary. All these components share a unified styling system that reads color configuration from the promotion's custom data.

Configuring Colors via SCAYLE Panel

You can customize the appearance of promotion code chips by setting custom colors in the promotion's customData within SCAYLE Panel. This is the recommended approach as it allows you to define colors per promotion without modifying code.

To configure custom colors:

  1. Navigate to your promotion in SCAYLE Panel.
  2. Update the "Background Color" and "Text Color" under "Visual Styling" of the promotion in questions. More information under "Promotions & Campaigns / Configuration".

The configured colors will automatically apply to promotion code chips and all other promotion UI elements throughout the storefront.

Advanced Customization

For more advanced customization needs beyond colors, you can modify the component styles directly in SFBasketPromotionCodes.vue or extend the getPromotionStyle() utility function in utils/promotion.ts.

Implementation Guide for Existing Projects

This guide walks you through adding the Promotion Codes feature to an existing SCAYLE Storefront Application. It covers installing the required packages, modifying components, adding translations, and configuring your project to support promotion code functionality.

This implementation guide is for existing tenant projects using a Storefront Application version before 1.11.0. Projects starting with v1.11.0 or higher include this feature out of the box. See the Storefront Application Changelog for details.

Starting with Storefront Application v1.12.0, projects use a Nuxt 4 compatible directory structure with the app/ directory as the source directory. Earlier versions may use different directory structures. The file paths in this guide use the <srcDir>/ directory placeholder. If your project uses a different structure, adjust the paths accordingly. For more information about this change, see the v1.12.0 changelog.

Prerequisites

  • Project based on SCAYLE Storefront Application (pre v1.11.0).
  • Valid access token for the SCAYLE Storefront Application Nuxt repository.
  • Node.js and package manager installed.

Step 1: Run the Storefront CLI feature:add command

The recommended approach for adding the Promotion Codes feature is using the Storefront CLI. The CLI automates the installation of required dependencies, copies necessary files into your project, and handles potential conflicts intelligently. If it detects a conflict with an existing file, it will prompt you to either override the file or save the new version with a .new suffix, allowing you to manually compare and integrate changes.

Execute the Storefront CLI feature:add command to add the Promotion Codes feature:

Be aware that you need to have the mentioned access token for the SCAYLE Storefront Application Nuxt repository ready, as this might be prompted if you're using this CLI command the first time.
You can also directly pass the access token via the CLI flag --access-token=YOUR-ACCESS-TOKEN.

For more information about the CLI and its capabilities, see the Storefront CLI features add documentation.

What this command does

  • Installs @scayle/storefront-promotions package (if not already present).
  • Registers the promotions module in your projects nuxt.config.ts (if not already registered).
  • Copies component files and utilities to your project.

What requires manual intervention

  • Adding translation keys to locale files.
  • Modifying existing components to integrate the feature.
  • Adding required icons (if not present).

Step 2: Review the copied Promotion Codes component

The CLI copies the SFBasketPromotionCodes.vue component to components/basket/. Review this component and customize it as needed to match your design system and requirements.

Component location:

Step 3: Integrate into Basket Summary

Add the promotion codes component to your basket summary page.

Modify <srcDir>/components/basket/summary/SFBasketSummary.vue and add the following import statement:

Add the component to the template (typically after the cost breakdown and before the checkout button):

Step 4: Add Translations

Add the required translation keys to your locale files. The CLI does not automatically inject translations.

Add to i18n/locales/en-GB.json and your other relevant locale files:

Translation key usage

  • headline - Section heading above the input field.
  • input_placeholder - Placeholder text in the input field.
  • input_label - ARIA label for screen readers.
  • add_code - ARIA label for the add button.
  • remove_code - ARIA label for remove buttons (includes {promotionCode} variable).
  • add_success - Success toast message.
  • add_error - Error toast message when adding fails.
  • remove_error - Error toast message when removal fails.

Step 5: Add Required Icons (Optional)

Ensure the following icons are available in your project:

Required icons:

  • IconPlus - Used for the "add code" button.
  • IconClose - Used for the "remove code" buttons on chips.

Icon locations:

These icons should be available in your icon set:

  • Via <srcDir>/assets/icons/ directory.
  • Via your preferred icon library.
  • As Vue components imported into the promotion codes component.

If these icons are not available, substitute them with equivalent icons from your project's icon system.

Step 6: Enhance the Text Input Component (Optional)

Depending on the Storefront Application version your project started with, the SFTextInput component might not yet include the append-icon slot. The promotion codes component however requires an append-icon slot in the SFTextInput component. This slot allows the addition of inline action buttons.

Modify modules/ui/runtime/components/form/SFTextInput.vue and add the following slot section before the closing </div> tag of the input wrapper:

Troubleshooting

Common Issues

Issue: Promotion code not applying

Possible causes:

  • Code doesn't exist in the system.
  • Code is not active (check start/end dates).
  • Code activation type is not set to "code".
  • Basket items don't meet promotion conditions.
  • Code has already been applied.

Solution:

  • Verify promotion configuration in SCAYLE Panel.
  • Check promotion activation type and code list.
  • Review promotion conditions and eligibility.
  • Check browser console for detailed error messages.

Issue: Multiple codes not working together

Possible cause:

  • Promotions are not configured to be combinable.

Solution:

  • In SCAYLE Panel, enable "Combinable with other promotions" in promotion settings.

Issue: Custom colors not displaying

Possible causes:

  • Custom data not properly configured in promotion.
  • getPromotionStyle() utility not imported or used correctly.
  • CSS conflicts overriding inline styles.

Solution:

  • Verify customData.color.background and customData.color.text are set in promotion.
  • Check that getPromotionStyle() is applied to the element.
  • Inspect element in browser DevTools to identify CSS conflicts.

Issue: Icons not displaying

Possible causes:

  • Icon components not imported.
  • Icon paths incorrect.
  • Using older or custom implementation of SFTextInput without append-icon slot.

Solution:

  • Verify icon imports at the top of the component.
  • Check that icon components are registered globally or imported locally.
  • Substitute with alternative icons from your project's icon system.
  • Use the copied SFTextInput from the latest Storefront Application (e.g. via Storefront CLI) or add append-icon into your custom component.

Debugging

Enable debug logging

The useApplyPromotions composable uses the Storefront logging system. Enable debug logs to see detailed information:

Check basket state by verifying API responses

Check Network tab in browser DevTools for RPC method calls:

  • updateBasketItem - When applying/removing promotions.
  • Verify request payload includes correct promotion IDs and codes.
  • Check response for updated basket state.

Known Limitations

  • Code case sensitivity: Promotion codes are case-sensitive by default.
  • Single redemption: One code can only be applied once per basket.
  • Real-time updates: Code validity is checked at the time of application, not continuously monitored.
  • Basket-level only: Promotion codes are applied at the basket level, not during browsing on other pages.

Getting Help

If you encounter issues not covered in this documentation:

  1. Review the Promotions & Campaigns documentation.
  2. Check the @scayle/storefront-promotions changelog for recent updates.
  3. Consult the SCAYLE Github Discussion Community.
  4. Contact SCAYLE support for further technical assistance.