Complete guide to the addBundleToCart mutation for adding configured product bundles to the WooCommerce cart.
The addBundleToCart mutation adds a fully configured bundle product to the cart.
| Field | Type | Required | Description |
|---|---|---|---|
productId | Int! | Yes | Bundle product database ID |
quantity | Int | No | Bundle quantity (default: 1) |
bundleItems | [BundleItemInput!] | No | Bundled item configuration |
extraData | String | No | JSON string of additional data |
| Field | Type | Required | Description |
|---|---|---|---|
bundleItemId | Int! | Yes | Bundled item ID from the bundle |
quantity | Int | No | Quantity for this item |
variationId | Int | No | Variation ID if bundled product is variable |
variation | [ProductAttributeInput] | No | Attribute selection for variable products |
optionalSelected | Boolean | No | Whether to include this optional item |
| Field | Type | Description |
|---|---|---|
cart | Cart | Updated cart object |
cartItem | BundleCartItem | The added bundle cart item |
Add a bundle with default configuration:
mutation AddBundleToCart($productId: Int!) { addBundleToCart(input: { productId: $productId, quantity: 1 }) { cart { contents { itemCount } total } cartItem { key quantity total } } }
Variables:
{ "productId": 123 }
mutation AddConfiguredBundle( $productId: Int! $bundleItems: [BundleItemInput!]! ) { addBundleToCart( input: { productId: $productId quantity: 1 bundleItems: $bundleItems } ) { cart { total } cartItem { key bundledItems { bundleItemId product { node { name } } quantity } } } }
Variables:
{ "productId": 123, "bundleItems": [ { "bundleItemId": 1, "quantity": 2 }, { "bundleItemId": 2, "quantity": 1 }, { "bundleItemId": 3, "quantity": 3 } ] }
Include or exclude optional items:
mutation AddBundleWithOptionals( $productId: Int! $bundleItems: [BundleItemInput!]! ) { addBundleToCart( input: { productId: $productId quantity: 1 bundleItems: $bundleItems } ) { cart { total } cartItem { bundledItems { bundleItemId optionalSelected quantity } } } }
Variables:
{ "productId": 123, "bundleItems": [ { "bundleItemId": 1, "quantity": 1 }, { "bundleItemId": 2, "quantity": 1, "optionalSelected": true }, { "bundleItemId": 3, "quantity": 0, "optionalSelected": false } ] }
When bundled items are variable products:
mutation AddBundleWithVariations( $productId: Int! $bundleItems: [BundleItemInput!]! ) { addBundleToCart( input: { productId: $productId quantity: 1 bundleItems: $bundleItems } ) { cart { total } cartItem { bundledItems { bundleItemId product { node { name } } variation { node { name attributes { nodes { name value } } } } quantity } } } }
Variables:
{ "productId": 123, "bundleItems": [ { "bundleItemId": 1, "quantity": 1, "variationId": 456 }, { "bundleItemId": 2, "quantity": 1, "variation": [ { "attributeName": "pa_color", "attributeValue": "blue" }, { "attributeName": "pa_size", "attributeValue": "large" } ] } ] }
The returned cart item includes bundle-specific fields:
fragment BundleCartItemFields on BundleCartItem { key quantity total subtotal # Bundle product product { node { name } } # Bundled items in cart bundledItems { bundleItemId quantity discount optionalSelected product { node { id name } } variation { node { id name attributes { nodes { name value } } } } } }
| Field | Type | Description |
|---|---|---|
bundleItemId | Int | ID matching the bundled item |
product | ProductConnection | The bundled product |
variation | VariationConnection | Selected variation (if applicable) |
quantity | Int | Quantity of this item |
discount | String | Applied discount |
optionalSelected | Boolean | Whether optional item was selected |
Building a bundle configuration form:
// Query bundle data first const BUNDLE_QUERY = gql` query GetBundle($id: ID!) { product(id: $id, idType: DATABASE_ID) { ... on BundleProduct { databaseId name bundleItems { edges { bundledItemId title optional minQuantity maxQuantity defaultQuantity node { databaseId name ... on VariableProduct { variations { nodes { databaseId name attributes { nodes { name value } } } } } } } } } } } `; // Build bundle items from user selection function buildBundleItems(bundleData, userSelections) { return bundleData.bundleItems.edges.map(edge => { const selection = userSelections[edge.bundledItemId]; return { bundleItemId: edge.bundledItemId, quantity: selection?.quantity ?? edge.defaultQuantity, variationId: selection?.variationId, optionalSelected: edge.optional ? selection?.included : undefined, }; }); } // Add to cart mutation const ADD_BUNDLE = gql` mutation AddBundle($productId: Int!, $bundleItems: [BundleItemInput!]!) { addBundleToCart( input: { productId: $productId quantity: 1 bundleItems: $bundleItems } ) { cart { total contents { itemCount } } cartItem { key total } } } `;
Common errors:
| Error | Cause |
|---|---|
Bundle product not found | Invalid product ID |
Invalid bundled item | bundleItemId doesn't belong to the bundle |
Quantity out of range | Quantity exceeds min/max limits |
Required item missing | Non-optional item not included |
Invalid variation | Variation doesn't match bundled product |
Bundle out of stock | Bundle or bundled item not in stock |
If the bundle is configured with editableInCart: true, use updateItemQuantities with modified bundle configuration:
mutation UpdateBundleInCart($key: ID!, $bundleItems: [BundleItemInput!]!) { updateItemQuantities( input: { items: [{ key: $key, quantity: 1, bundleItems: $bundleItems }] } ) { cart { total } } }
Creates a new bundle product with bundled item definitions. See the Mutations Reference for full input/output details.
mutation CreateBundle($input: CreateBundleProductInput!) { createBundleProduct(input: $input) { product { databaseId ... on BundleProduct { bundleItems { edges { bundledItemId title } } } } } }
Variables:
{ "input": { "name": "Starter Kit", "regularPrice": 49.99, "bundledItems": [ { "productId": 101, "quantityMin": 1, "quantityMax": 3, "quantityDefault": 1, "pricedIndividually": true }, { "productId": 102, "optional": true, "discount": "10" } ] } }
Updates an existing bundle product. Provide id to identify the product.
mutation UpdateBundle($input: UpdateBundleProductInput!) { updateBundleProduct(input: $input) { product { databaseId name } } }
Bundle product mutations also accept addons and excludeGlobalAddons fields for managing per-product add-on definitions. See Per-Product Addon Fields.