I’m looking for a way to create a discount code that is only applicable for 1/x items in a cart (of a certain collection). For example, I want customers to get 5% off their first product when they sign up for our newsletter. If they decide to order 3 items in that order, i dont want them to get 5% off each of them, this discount is simply too much. I need the 5% to apply to only one of their item and not to the rest.
. In Shopify Admin > Discounts, create a 5% discount code (e.g., “WELCOME5”).
.Set it to apply only to specific product or collections.
Add Custom Logic in the Cart Page
.In your cart template (cart.liquid), or if your theme supports it, in theme.js or a custom script file, use JavaScript to ensure the discount only applies to the first eligible product.
Here’s an example of what the JavaScript might look like:
document.addEventListener('DOMContentLoaded', function () {
const discountCode = 'WELCOME5';
let discountApplied = false;
const eligibleItems = document.querySelectorAll('.cart-item[data-collection-id="123456789"]'); // Replace with collection ID
if (eligibleItems.length > 0 && !discountApplied) {
// Add the discount code to the first eligible item only
fetch(`/discount/${discountCode}`)
.then(() => {
console.log('5% discount applied to the first item!');
discountApplied = true;
})
.catch((error) => console.error('Discount application failed:', error));
}
});
If I managed to help you then, don’t forget to Like it and Mark it as Solution!
I have followed the steps you have provided. First, I created a welcome5 discount for specific collections. Then, I created a new cart template called “cart.welcome.liquid” file in the templates of my theme (dawn). I copied the javascript you have provided for the “cart.welcome.liquid” file.
However it does not work. It still applies the 5% on all the products in the cart.
Attached is the cart.welcome.liquid which I created in the templates file.:
You can achieve this by using automatic discounts for specific products or collections. However, Shopify’s built-in discount system applies the discount to all qualifying items in the cart. To limit the discount to just one item, you might need a third-party app like “Discount Ninja” or “Automatic Discounts & Gifts,” which allow more advanced discount rules like applying to only the first item in a cart.
Update your cart.welcome.liquid file to track the first eligible item. Use Liquid to assign a special flag (via line properties) only to the first product in the cart.
liquid:
This template checks if the first item in the cart and applies a 5% discount using the formula Item.line_price | times:0.95.
We use <input type=“hidden” name="properties[discount_applied] to flag that the discount has been applied.
Add this JavaScript to ensure that the discount only applies to the first product and isn’t reapplied during cart updates.
document.addEventListener('DOMContentLoaded', function () {
const discountApplied = document.querySelector('input[name="properties[discount_applied]"]');
if (discountApplied) {
console.log('5% discount already applied to the first item.');
} else {
console.warn('Discount not applied properly.');
}
// Disable further discount application on other items
document.querySelectorAll('.cart-item:not(:first-child)').forEach(item => {
item.querySelector('input[name^="updates"]').disabled = true;
});
});
This script ensures that the first product is the only one eligible for the 5% discount.
If the discount is applied, we prevent the user from adjusting the price on other products via the cart interface.
thanks a lot for your help. i am very native but willing to learn.
So I have updated the cart.welcome.liquid file with the html you suggested above. This is now how cart.welcome.liquid.file looks like :
document.addEventListener('DOMContentLoaded', function () {
const discountCode = 'WELCOME5';
let discountApplied = false;
const eligibleItems = document.querySelectorAll('.cart-item[data-collection-id="van-cleef-arpels"]'); //
if (eligibleItems.length > 0 && !discountApplied) {
// Add the discount code to the first eligible item only
fetch(`/discount/${discountCode}`)
.then(() => {
console.log('5% discount applied to the first item!');
discountApplied = true;
})
.catch((error) => console.error('Discount application failed:', error));
}
});
document.addEventListener('DOMContentLoaded', function () {
const discountApplied = document.querySelector('input[name="properties[discount_applied]"]');
if (discountApplied) {
console.log('5% discount already applied to the first item.');
} else {
console.warn('Discount not applied properly.');
}
// Disable further discount application on other items
document.querySelectorAll('.cart-item:not(:first-child)').forEach(item => {
item.querySelector('input[name^="updates"]').disabled = true;
});
});
It still does not work :(… should I create another template for this javascript below?
document.addEventListener('DOMContentLoaded', function () {
const discountApplied = document.querySelector('input[name="properties[discount_applied]"]');
if (discountApplied) {
console.log('5% discount already applied to the first item.');
} else {
console.warn('Discount not applied properly.');
}
// Disable further discount application on other items
document.querySelectorAll('.cart-item:not(:first-child)').forEach(item => {
item.querySelector('input[name^="updates"]').disabled = true;
});
});
Define your discount percentage and collection name
DISCOUNT_PERCENTAGE = 5.0
TARGET_COLLECTION_HANDLE = ‘your-collection-handle’ # Replace with your collection handle
Initialize a variable to track if the discount has been applied
discount_applied = false
Loop through all line items in the cart
Input.cart.line_items.each do |line_item|
product = line_item.variant.product
Check if the product is in the specified collection and if the discount hasn’t been applied yet
if product.collections.map(&:handle).include?(TARGET_COLLECTION_HANDLE) && !discount_applied
Apply the discount to the first item only
line_item.change_line_price(line_item.line_price * (1 - DISCOUNT_PERCENTAGE / 100.0), message: “5% discount applied!”)
discount_applied = true # Set the flag to true so only one discount applies
end
end
Output the modified cart
Output.cart = Input.cart
Replace ‘your-collection-handle’ with the actual handle of the collection you want to target.
Log in to your Shopify Admin.
Navigate to Products in the left-hand sidebar.
Click on Collections.
Select the specific collection you want to find the handle for.
In the collection details page, look at the URL in your browser’s address bar. The collection handle is the last part of the URL.
Shopify website doesn’t natively support discounts for a specific number of items in the cart. However, you can use an app like Automatic Discounts & Gifts or Discount Ninja to apply advanced discount logic.
Set the discount to apply to the first item of the selected collection.
Ensure that the app you choose allows limiting the discount to only one item per cart.
hi thanks for your help but this solution does not work as The Script Editor app is no longer available for download from the Shopify App Store… Do you happen to have any other solution to propose ? thank you!
I have updated the file but it still does not work. Just to be clear, in the discount code I have specified the collection van-cleef-arpels. When I try with the 2 products that are both in the same ID collection van-cleef-arpels; it still does not work.
@lossa , native discounts don’t let you specify an upper limit to the number of discounts. I suggest you try our app, Discount Bot. You can set a limit to the number of percentage discounts: