All things Shopify and commerce
I have a javascript code that adds multiple products to my cart add once.
Based on this documentation: Add products to cart
This normally works if non of the products has a issue like:
This are the basic response that i could get when doing this.
However it looks like all the other products are also not added to the cart when their is a issue.
Does anyone has a idee how to make these calls so that the products are added to cart except for the once that triggers those errors?
Solved! Go to the solution
This is an accepted solution.
You're welcome!
Just to clarify — in my example, the setTimeout wasn't for rate limiting — it was simply used to wait a bit before summarizing/logging how many products were added or failed (because the fetch calls are asynchronous).
But you're right to think about rate limits — Shopify does have limits (especially ~2 requests per second for storefront APIs like /cart/add.js).
If you are adding many products (like more than 2–3 at once), and you want to properly handle rate limits, you should actually queue the requests with a delay between them instead of blasting them all at once with forEach.
Here's a better version using a small delay between each request:
async function addProductsToCart(products) {
let errors = [];
let successfulAdds = 0;
for (const product of products) {
try {
await addProductToCart(product);
successfulAdds++;
console.log(`Product ${product.id} added successfully.`);
} catch (error) {
errors.push({ product: product, error: error });
console.log(`Error adding product ${product.id}: ${error.message}`);
}
// Wait 300ms between requests to be safe
await new Promise(resolve => setTimeout(resolve, 300));
}
console.log(`${successfulAdds} products added to the cart.`);
if (errors.length > 0) {
console.log('Failed to add the following products:');
errors.forEach(err => console.log(`Product ${err.product.id} failed due to: ${err.error.message}`));
}
}
Now each product will be added one by one, with a small 300ms pause between them to avoid hitting Shopify's rate limits.
In short:
. setTimeout in the first example = just waiting before logging the summary.
. Proper rate limiting = add a delay (await new Promise(resolve => setTimeout(resolve, 300))) after each product like in this new code.
. Shopify cart APIs aren't super strict, but it's still a good idea to throttle your requests when adding multiple items at once.
Thank you 😊
Hello @Michel2025
To ensure that all products are added to the cart except the ones that trigger errors like "out of stock," "draft product," or "variant not found," you can modify your JavaScript code to handle each product individually. Instead of stopping the entire process when one product fails, you can process each product separately and catch the errors for each one. Here's a general approach you can follow:
Approach:
1. Loop through the products: For each product, you try to add it to the cart.
2. Error handling: If the product has an error (like being out of stock or a draft product), catch the error and skip adding that product to the cart.
3. Continue with other products: Continue processing the remaining products, even if one fails.
Example JavaScript Code:
function addProductsToCart(products) {
let errors = []; // To store products that fail
let successfulAdds = 0; // To track the successful additions
// Loop through each product and try adding it to the cart
products.forEach(product => {
addProductToCart(product)
.then(response => {
successfulAdds++;
console.log(`Product ${product.id} added successfully.`);
})
.catch(error => {
errors.push({ product: product, error: error });
console.log(`Error adding product ${product.id}: ${error.message}`);
});
});
// After all products are processed, log the results
setTimeout(() => {
console.log(`${successfulAdds} products added to the cart.`);
if (errors.length > 0) {
console.log('Failed to add the following products:');
errors.forEach(err => console.log(`Product ${err.product.id} failed due to: ${err.error.message}`));
}
}, 1000); // Adjust time if needed based on your network latency or number of products
}
function addProductToCart(product) {
return new Promise((resolve, reject) => {
// Your logic to add the product to the cart
// This example assumes you're using Shopify's AJAX API to add the product
let formData = {
items: [
{
id: product.variantId,
quantity: product.quantity
}
]
};
fetch('/cart/add.js', {
method: 'POST',
body: JSON.stringify(formData),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
if (data.status && data.status === 404) {
reject(new Error('Variant not found'));
} else if (data.status && data.status === 422) {
reject(new Error('Out of stock'));
} else if (data.status && data.status === 500) {
reject(new Error('Product is a draft'));
} else {
resolve(data);
}
})
.catch(err => reject(err));
});
}
Explanation:
. addProductsToCart(products): This function processes the list of products and attempts to add each one to the cart. If there's an error, it catches the error and logs it.
. addProductToCart(product): This function attempts to add a single product to the cart using Shopify's /cart/add.js API. It returns a promise that resolves if the product is added successfully or rejects with an error message if it fails (e.g., variant not found, out of stock, or product is a draft).
. The loop ensures that all products are processed, and even if one fails, the rest will still be added.
Error Handling:
. The catch block inside the forEach ensures that the script continues executing even if a product fails to add to the cart.
. reject(new Error('Variant not found')) and other similar errors are triggered when certain conditions (like the product being out of stock or not found) occur.
This approach should allow products to be added to the cart independently, even if some fail due to issues like those you mentioned.
Thank you 😊
Thank you, i will look if your solution could help me.
The setTimeout is for the rate limit(to many request) i guess
This is an accepted solution.
You're welcome!
Just to clarify — in my example, the setTimeout wasn't for rate limiting — it was simply used to wait a bit before summarizing/logging how many products were added or failed (because the fetch calls are asynchronous).
But you're right to think about rate limits — Shopify does have limits (especially ~2 requests per second for storefront APIs like /cart/add.js).
If you are adding many products (like more than 2–3 at once), and you want to properly handle rate limits, you should actually queue the requests with a delay between them instead of blasting them all at once with forEach.
Here's a better version using a small delay between each request:
async function addProductsToCart(products) {
let errors = [];
let successfulAdds = 0;
for (const product of products) {
try {
await addProductToCart(product);
successfulAdds++;
console.log(`Product ${product.id} added successfully.`);
} catch (error) {
errors.push({ product: product, error: error });
console.log(`Error adding product ${product.id}: ${error.message}`);
}
// Wait 300ms between requests to be safe
await new Promise(resolve => setTimeout(resolve, 300));
}
console.log(`${successfulAdds} products added to the cart.`);
if (errors.length > 0) {
console.log('Failed to add the following products:');
errors.forEach(err => console.log(`Product ${err.product.id} failed due to: ${err.error.message}`));
}
}
Now each product will be added one by one, with a small 300ms pause between them to avoid hitting Shopify's rate limits.
In short:
. setTimeout in the first example = just waiting before logging the summary.
. Proper rate limiting = add a delay (await new Promise(resolve => setTimeout(resolve, 300))) after each product like in this new code.
. Shopify cart APIs aren't super strict, but it's still a good idea to throttle your requests when adding multiple items at once.
Thank you 😊
Hi,
Hope this will help
- You need to add each product one by one, and if one fails, keep going.
JavaScript version example
const productsToAdd = [
{ id: 123456789, quantity: 1 },
{ id: 987654321, quantity: 2 },
{ id: 112233445, quantity: 1 }
];
async function addProductToCart(product) {
try {
const response = await fetch('/cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
items: [product]
})
});
const data = await response.json();
console.log(`Added product ${product.id} to cart.`);
} catch (error) {
console.warn(`Could not add product ${product.id}:`, error.message);
}
}
async function addAllProducts(products) {
for (const product of products) {
await addProductToCart(product);
}
console.log('Done trying to add all products!');
}
addAllProducts(productsToAdd);
Learn how to build powerful custom workflows in Shopify Flow with expert guidance from ...
By Jacqui May 7, 2025Did You Know? May is named after Maia, the Roman goddess of growth and flourishing! ...
By JasonH May 2, 2025Discover opportunities to improve SEO with new guidance available from Shopify’s growth...
By Jacqui May 1, 2025