Skip to main content

Selectable Gift Offers with a Cart Cross-Sell Widget (Custom Code Method)

Hand-build a selectable gift offer with a Cart Cross-Sell widget and custom JavaScript, the method before Selectable Gift with Purchase.

Written by Tom

Use the Selectable Gift with Purchase widget for new gift offers!

Rebuy now has a dedicated Selectable Gift with Purchase widget that lets shoppers choose their own free gifts, and Rebuy recommends it instead of the custom-code method in this article for every new customer-choice gift offer.

The Selectable Gift with Purchase widget is created from the Widgets page in the Rebuy admin with no custom JavaScript, and its setup is covered in Selectable Gift with Purchase Widget: Let Shoppers Choose Their Free Gift.

Follow this article only if you are maintaining a gift offer that was already built from a Cart Cross-Sell widget and custom JavaScript.

This article covers building a customer-choice gift offer by hand from a Cart Cross-Sell widget and custom JavaScript, which is the method merchants used before the Selectable Gift with Purchase widget existed.

Note: The custom-code method in this article requires Rebuy's Smart Cart, because the JavaScript below calls Rebuy.SmartCart.items() and Rebuy.Cart.removeItem(). The native Selectable Gift with Purchase widget type can also be placed on a product page or across the whole store, where no Smart Cart is involved.

The custom-code method in this article has two display styles:

  • Pop-up: The gift selection appears as a popup overlay triggered by a cart action, such as adding an item to the cart. The shopper selects a gift from the popup and it is added to the Smart Cart.

  • Embedded: The gift selection appears directly inside the Smart Cart drawer as an inline widget. The shopper selects a gift from within the cart itself.

Both styles use the same underlying widget configuration, differing in the display settings and the custom code applied in the Advanced tab.

Choosing the right gift with purchase approach

Rebuy offers several ways to add a free gift to an order. The table below matches each scenario to the approach that fits it, with the setup guide for each.

Scenario

Recommended approach

Shopper chooses their own gift, and you want a supported no-code setup

Shopper chooses their own gift, and you are maintaining an offer already built with custom code

The Cart Cross-Sell method in this guide

One gift product, no variant selection needed

One gift product, shopper must choose a variant such as size or color

Selectable gift offer delivered at Shopify Checkout, Shopify Plus only

Checkout Extensions recommendation widget with Treat as Gift With Purchase enabled. See Checkout Extensions Installation and Settings

Setting Up a Selectable Gift With Purchase Widget

The following steps walk you through the full setup for a Selectable Gift With Purchase widget. These steps apply to both the pop-up and embedded display styles. After completing this setup, follow the display-specific instructions in the section for your chosen style (pop-up or embedded).

Step 1: Create a Cross-Sell Widget in Smart Cart

To create a Selectable Gift With Purchase widget, you start by adding a cross-sell widget component to your Rebuy Smart Cart.

  1. Navigate to the Rebuy Dashboard and open the Smart Cart editor you want to add the widget to.

  2. Click "Add +" in the Cross-Sells Component within the Smart Cart editor.

  3. Select Cross-Sell Widget from the component list and create a new Widget.

  4. Once the cross-sell widget is created, click on the widget name or the settings icon to open its configuration editor.

Step 2: Enable the Discount Using Shopify Functions

To ensure that the free gift product displays as Free in the widget, the Smart Cart, and at checkout, you need to enable the discount setting in the widget's configuration. Rebuy uses Shopify Functions to create an automatic discount that applies to the gift product when a customer selects it.

  1. In the widget's editor, locate the Discount tab.

  2. Select Discount Type "Percentage"

  3. Toggle ON the discount setting "Discounted By Functions". This creates an Automatic Discount in Shopify scoped to widget and the discount will be automatically applied to the applicable items when a customer adds them from the widget.

  4. Configure the discount to apply a 100% discount to the gift products.

Shopify Functions for discounting is available for all Shopify plan types. For more information on how discounting works with Shopify Functions in Rebuy, see the Rebuy Discounting Overview.

Note: If you prefer to create and manage your own discount setup directly in Shopify instead of having Rebuy create the discount automatically, toggle off the Shopify Functions setting. Rebuy will still display the product as free in the widget, but you will be responsible for configuring a matching discount in Shopify to ensure the gift is actually discounted at checkout.

Important: Avoid using a $0-priced product as your gift. Instead, give the product a real price and let the Use Shopify Functions setting discount it to $0 for qualifying customers. A $0 product can cause exploits because any customer who finds the product URL can add it to their cart for free — without qualifying for the promotion. Giving the gift a real price and using Shopify Functions to discount it to $0 only for qualifying customers prevents this.

Step 3: Configure Data Source Rules

The Data Source rules determine when the Selectable Gift With Purchase widget appears to the customer. These rules define the conditions a customer's cart must meet before the gift offer is triggered.

  1. Open the Data Source tab in the widget's settings.

  2. Leave the Filter input products checkbox unchecked.

  3. Add a rule that matches your promotion's conditions.

The most common rule is a cart subtotal threshold (for example, "Show this widget when the cart subtotal is $249.99 or more"). Other conditions you can use include rules based on specific products in the cart, cart item count, customer tags, or any other supported Rebuy rule.

Important: Leave the Filter input products checkbox unchecked for Selectable GWP widgets. Because this is a Cart Cross-Sell widget, its Data Source uses the items currently in the cart as input products. If Filter input products is enabled, the Data Source will filter out any gift products if they had already been added to the cart, which can cause the widget to return no products and break the selection flow. The custom JavaScript code added in a later step already handles hiding the widget after a gift is selected — the Data Source filter should not duplicate that logic.

For a full overview of how Data Sources work, see Data Sources 101. For cart-specific rule options, see Data Sources and the Cart.

Step 4: Choose Your Display Style (Embedded or Pop-Up)

After completing Steps 1 through 3, choose how the Selectable Gift With Purchase widget will appear to your customers. There are two display styles, and each requires its own configuration in the widget settings and custom code in the Advanced tab.


How to Create an Embedded Selectable Gift With Purchase Widget

An embedded Selectable Gift With Purchase widget displays the gift selection directly inside the Smart Cart drawer as an inline component. Instead of a popup overlay, the gift options appear within the cart itself, and the widget hides after the customer selects a gift.

Add the Embedded Custom Code

The embedded Selectable Gift With Purchase widget requires custom JavaScript code to control when the widget is visible inside the Smart Cart. This code checks whether the customer has already selected a gift, hides the widget when a gift is in the cart, and removes the gift if the Data Source conditions are no longer met.

  1. In the widget's editor, open the Advanced tab.

  2. Copy the following code and paste it into the Ready section of the Advanced tab:

function embedSelectableGWP () { 
setTimeout(() => {
//check for a free gift item in the cart
const giftItem = Rebuy.SmartCart.items().find(item => item.properties?._widget_id === `${widget.id}`);
//hide widget if there is a gift item
if (giftItem) {
document.querySelector(`#rebuy-widget-${widget.id}`).style.display = 'none';
//display the widget if not
} else {
document.querySelector(`#rebuy-widget-${widget.id}`).style.display = 'block';
}
//if widget rules is no longer match, remove free gift
if (widget.data?.metadata.matched_rules.length === 0) {
Rebuy.Cart.removeItem(giftItem)
}
}, 500)
}
//runs on page load
embedSelectableGWP()
//runs on each cart change
document.addEventListener('rebuy:cart.change', embedSelectableGWP)

This code does three things:

  1. Checks for an existing gift. It looks through the Smart Cart line items to find any product that was added by this specific widget (identified by the widget ID).

  2. Shows or hides the widget. If no gift from this widget is in the cart and the Data Source rules are currently matched, the widget is displayed inside the Smart Cart. If a gift has already been selected, the widget is hidden using display: none so the customer only sees the gift as a regular line item in the cart.

  3. Removes the gift if conditions change. If the customer modifies their cart so the Data Source rules are no longer met, the gift is automatically removed from the cart.

The code runs once on page load and then again every time the cart changes, using the rebuy:cart.change event listener.

Embedded Selectable GWP: See It in Action

To see an embedded Selectable Gift With Purchase widget in action, watch the video walkthrough linked below. The video demonstrates a customer opening the Smart Cart, seeing the gift selection widget inline within the cart, choosing a free gift, and the widget hiding once the gift is added.


How to Create a Pop-Up Selectable Gift With Purchase Widget

A pop-up Selectable Gift With Purchase widget displays the gift selection as a popup overlay that appears on top of the Smart Cart. The popup is triggered by a cart action (typically when a customer adds an item to the cart) and prompts the customer to choose a free gift before continuing.

Set the Display Type to Pop-Up

Configure the widget to display as a popup instead of an inline embed within the Smart Cart.

  1. In the widget's settings panel, expand the Widget Settings tab.

  2. Under Display Type, select Popup.

Add the Pop-Up Custom Code

The pop-up Selectable Gift With Purchase widget requires custom JavaScript code to control when the popup appears and when it is hidden. This code checks whether the customer has already selected a gift, shows the popup when the Data Source conditions are met, and removes the gift from the cart if the conditions are no longer met.

  1. In the widget's settings panel, expand the Advanced tab.

  2. Copy the following code and paste it into the Ready section of the Advanced tab:

function popupSelectableGWP() {
setTimeout(() => {
//check for free gift items in the cart
const giftItem = Rebuy.SmartCart.items().find((item) => item.properties._widget_id === `${widget.id}`);
//if there is no gift item and the widget rules match
if (!giftItem && widget.data.metadata.matched_rules.length) {
widget.show();
//hide the widget if theres already a gift in cart
} else {
widget.hide();
}
//if widget rules is no longer match, remove free gift
if (widget.data?.metadata.matched_rules.length === 0) {
Rebuy.Cart.removeItem(giftItem);
}
}, 300);
}
popupSelectableGWP(); //runs on page load
document.addEventListener("rebuy:cart.change", popupSelectableGWP); //runs on cart change

This code does three things:

  1. Checks for an existing gift. It looks through the Smart Cart line items to find any product that was added by this specific widget (identified by the widget ID).

  2. Shows or hides the popup. If no gift from this widget is in the cart and the Data Source rules are currently matched, the popup is displayed. If a gift has already been selected, the popup stays hidden.

  3. Removes the gift if conditions change. If the customer modifies their cart so the Data Source rules are no longer met (for example, they remove items and the subtotal drops below the threshold), the gift is automatically removed from the cart.

The code runs once on page load and then again every time the cart changes, using the rebuy:cart.change event listener.

Pop-Up Selectable GWP: See It in Action

To see a pop-up Selectable Gift With Purchase widget in action, watch the video walkthrough linked below. The video demonstrates a customer adding items to the cart, triggering the gift selection popup, choosing a free gift, and seeing it added to the Smart Cart with the discount applied.


Optional: Customizing the Gift Line Item in Smart Cart

After setting up your Selectable Gift With Purchase widget, you may want to adjust how the gift line item appears inside the Smart Cart. The following optional steps use CSS to hide default Smart Cart elements on the gift line item or to prevent customers from clicking through to the gift product's page.

Hide the Quantity Selector and Subscription Option on the Gift Line Item

By default, Smart Cart line items display a quantity selector and a subscription upgrade option. To prevent customers from changing the quantity of the free gift or being prompted to subscribe, add CSS code to hide these elements on any line item added by the GWP widget.

Add the following CSS to your Rebuy Theme by navigating to Settings > Themes in the Rebuy Dashboard and pasting the code into the CSS input:

.property-value-XXXXX .rebuy-cart__flyout-item-quantity-widget {
display: none;
}

.property-value-XXXXX .rebuy-cart__flyout-item-subscription {
display: none;
}

Important: Replace XXXXX with your widget's actual ID number. You can find the widget ID in the widget's settings panel or in the URL when editing the widget.

Disable Product Page Links on the Gift Line Item

This step is only necessary if the free gift products you are offering are hidden from all other areas of your online store and you do not want customers to be able to click through to those product pages from within the Smart Cart.

To remove the clickable link on the gift line item's product title and image in the Smart Cart, add the following CSS to Smart Cart > Custom CSS:

/* Replace XXXXX with the widget's ID */
.rebuy-cart__flyout-item.property-value-XXXXX .rebuy-cart__flyout-item-product-title,
.rebuy-cart__flyout-item.property-value-XXXXX .rebuy-cart__flyout-item-media {
pointer-events: none;
}

Important: Replace XXXXX with your widget's actual ID number.


Optional: Pairing with the Tiered Progress Bar using the Decorative Tier

A Selectable Gift With Purchase widget can be paired with a Decorative Tier in Rebuy's Tiered Progress Bar to give customers a visual progress milestone toward their gift selection. The Decorative Tier handles the progress bar display — showing customers how close they are to the threshold — while the Selectable GWP widget handles the gift selection experience when they get there.

The Decorative Tier is a display-only tier type in the Tiered Progress Bar. It does not automatically add a gift or apply a discount on its own. When paired with a Selectable GWP widget, the Decorative Tier shows the cart milestone and the widget triggers the gift selection popup or embedded offer when the customer's cart meets your Data Source Rules.

The screenshot below shows an example of a Tiered Progress Bar Decorative Tier paired with a Selectable Gift With Purchase widget for customer-choice gift rewards.

How to pair the Selectable GWP Widget with the Tiered Progress Bar Decorative Tier

To pair a Selectable GWP widget with a Tiered Progress Bar Decorative Tier:

  1. Set up your Selectable GWP widget using the steps in this guide.

  2. In your widget's Data Source Rules, add a Cart Subtotal rule set to "Is Greater Than" and enter an amount just below your intended threshold (for example, if your threshold is $100, set the rule to $99).

  3. In your Smart Cart editor, open the Tiered Progress Bar component and add a new tier.

  4. Set the tier type to Decorative-Only.

  5. Set the Unlock Price to your threshold amount (for example, $100).

  6. Add a Decorative Tier Label that describes the reward (for example, "Choose Your Free Gift").

  7. Save your changes.

Important: The Cart Subtotal rule uses "Is Greater Than," so set your rule value $1 below your Decorative Tier's Unlock Price. For example, if your Unlock Price is $100, set the rule to "Cart Subtotal Is Greater Than $99." This ensures the progress bar milestone and the Selectable GWP widget both trigger at the same cart value.

For full instructions on setting up the Decorative Tier — including label copy, icon configuration, and the full setup walkthrough — see Using the Decorative Tier in Rebuy's Tiered Progress Bar.


Frequently Asked Questions About Selectable Gift With Purchase

Can I use a Selectable Gift With Purchase widget for a "Buy X, Get One Free" (BOGO) promotion?

Yes, but only when the qualifying product and the gift product are different items (Buy X, Get Y). For example, you can set a Data Source rule like "IF Cart Contains [Product A], RETURN [Product B]" and the widget will work as expected. The discount setting using Shopify Functions will ensure the selected gift is discounted to free at checkout.

Important: Buy X, Get X (same product) is not supported. The Selectable GWP widget cannot handle a true Buy X, Get X offer where the qualifying product and the gift product are the same item. This creates an infinite loop: the widget automatically adds the gift to the cart, but because the gift is the same product as the qualifying item, the widget treats it as another qualifying purchase. If the customer removes the free item, the widget adds it back, and the cycle repeats.

For example, a "Buy 1 red candle, Get 1 red candle free" promotion would loop — the customer removes the free candle, and the widget immediately adds it back.

Can a shopper select more than one free gift from the custom-code Cart Cross-Sell method?

No, the custom-code Cart Cross-Sell method in this guide allows one gift only. Once a gift is added to the cart, the code hides the widget so the shopper cannot add a second gift from it. Allowing more than one gift would mean modifying the JavaScript in the Advanced tab yourself. Rebuy's Selectable Gift with Purchase widget type supports multiple gifts natively through its Milestones settings, where each milestone adds to the number of gifts a shopper can claim.

What happens if a shopper removes items from their cart and no longer qualifies for the free gift?

The custom JavaScript in this guide removes the gift on the next cart change event. If a shopper modifies their cart so the Data Source conditions for the Cart Cross-Sell widget are no longer met, for example the promotion requires a $50 cart subtotal and the shopper drops below $50, the code calls Rebuy.Cart.removeItem() and the gift leaves the cart.

What happens if a shopper removes items at Shopify Checkout and drops below the qualifying threshold?

With the custom-code Cart Cross-Sell method in this guide, the gift product stays in the order. The JavaScript in this guide runs on the storefront only and has no checkout validation, so the Shopify Functions discount falls off the gift line and the shopper is charged for it, but the product itself remains. The shopper would need to return to the storefront and remove it manually.

Rebuy's Selectable Gift with Purchase widget type reconciles claimed gifts on every Shopify plan, on every cart change and again when the shopper clicks the checkout button in the cart, so the cart that reaches Shopify Checkout never carries more gifts than it qualifies for. On Shopify Plus stores with a Rebuy Smart Component block placed in checkout, the Selectable Gift with Purchase widget type also removes surplus gifts on the Shopify Checkout page itself.

Can I use a different discount method instead of Shopify Functions?

Rebuy's recommended approach for discounting Selectable Gift With Purchase products is Shopify Functions, which is available on all Shopify plan types. If you toggle off the Shopify Functions setting in the widget, Rebuy will display a visual discount in the widget (showing the product as free), but the full price will be charged at checkout. For more details on discount options, see the Rebuy Discounting Overview.

Does the custom-code Cart Cross-Sell method work without Rebuy's Smart Cart?

No, the custom-code method in this guide requires Rebuy's Smart Cart, because the JavaScript it depends on calls Smart Cart's own API, Rebuy.SmartCart.items() and Rebuy.Cart.removeItem(). It cannot be used with Shopify's native cart or a third-party cart.

Rebuy's Selectable Gift with Purchase widget type is not limited this way. Its Cart location does require the Smart Cart, and its Product Page and Global locations install through the Rebuy Widget app block in your Shopify theme with no Smart Cart involved.

How do I find my widget ID to use in the CSS code?

Your Rebuy widget ID is a numeric identifier assigned to each widget. You can find it in two places: in the widget's settings panel at the top of the page, or in the browser's URL bar when you are editing the widget (it appears as a number in the URL path). Use this ID to replace XXXXX in the CSS code snippets provided in this guide.


Troubleshooting Selectable Gift With Purchase Widgets

The pop-up is not appearing when items are added to the cart

If the Selectable Gift With Purchase popup is not appearing when a customer adds items to the cart, check the following:

  • Data Source rules: Verify that the Data Source conditions are being met. Open the widget's Data Source tab and confirm the rules match the current cart state (for example, the cart subtotal meets the threshold).

  • Display Type: Confirm the widget's Display Type is set to Popup and the trigger is set to Add to cart in the Widget Settings tab.

  • Advanced code: Make sure the custom JavaScript code is pasted into the Ready section of the Advanced tab (not the CSS or HTML sections). Check for any JavaScript errors in the browser console.

  • Existing gift in cart: The code intentionally hides the popup if a gift from this widget is already in the cart. If you are testing, clear the cart completely and try again.

The free gift is not being removed when the customer no longer qualifies

If the free gift stays in the cart after the customer's cart no longer meets the Data Source conditions, confirm that the custom code in the Advanced tab includes the rule-matching check. The relevant code block checks widget.data?.metadata.matched_rules.length === 0 and calls Rebuy.Cart.removeItem(giftItem). If this check is missing or modified, the automatic removal will not work.

Also verify that the rebuy:cart.change event listener is included at the bottom of the code. Without this listener, the code only runs on page load and will not react to subsequent cart changes.

If the free gift stays in the cart at Shopify Checkout after the subtotal drops below the qualifying threshold, that is expected for the custom-code Cart Cross-Sell method in this guide. The JavaScript here runs on the storefront and has no checkout validation, so the discount comes off the gift line but the product itself stays in the order, and the shopper has to return to the storefront to remove it. Rebuilding the offer on Rebuy's Selectable Gift with Purchase widget type adds automatic gift removal on the Shopify Checkout page for Shopify Plus stores with a Rebuy Smart Component block placed in checkout.

The gift product is not showing as free at checkout

If the gift product displays as free in the Rebuy widget and Smart Cart but is charged at full price during checkout, check the following:

  • Shopify Functions toggle: In the widget's settings, confirm that the Shopify Functions discount toggle is enabled. If this toggle is off, Rebuy only applies a visual discount in the widget — the actual price is not discounted at checkout.

  • Discount conflicts: Check whether any other Shopify discount codes or automatic discounts are conflicting with the Rebuy Shopify Functions discount. Shopify limits the number of automatic discounts that can be combined.

  • Cart subtotal dropped below the threshold at checkout: The Selectable Gift With Purchase widget does not run checkout validation logic. If the cart subtotal drops below the qualifying threshold at checkout — from removing items, applying a discount code, or any other cart change — the discount on the gift will be removed but the gift product itself will remain. The customer would need to return to the storefront to remove it manually.

  • For more details, see the Rebuy Discounting Overview.

Did this answer your question?