---
title: "Force Sells developer reference"
url: "https://kestrelwp.com/docs/force-sells-developer-reference/"
description: "Filters and recipes for changing how Force Sells behaves in code."
published: "2026-10-06T20:27:00+00:00"
modified: "2026-10-08T19:57:17+00:00"
---

Force Sells has no settings screen, so changes to how it behaves are made with a few filters in a small custom plugin or your theme’s `functions.php`. This page lists those filters, a recipe for each common change, and the data Force Sells adds to the Store API cart. For setting up force sells on products, see [Get started with Force Sells](/docs/get-started-with-force-sells/).

## Filters

### wc\_force\_sell\_add\_to\_cart\_product

Filters what’s added to the cart for each linked product, just before it’s added.

- `$params` (array): `id` (the product, or the parent of a variation), `quantity` (the quantity being added of the main product), `variation_id` (the variation, or an empty string) and `variation` (variation attributes, empty by default).
- `$parent_cart_item` (array): the main product’s cart item.

Return the array, changed as needed. It runs for both normal and synced force sells.

### wc\_force\_sell\_update\_quantity

Filters the new quantity of a synced force sell when the shopper changes the main product’s quantity or removes it.

- `$quantity` (int|float): the main product’s new quantity, or 0 when it’s removed.
- `$cart_item` (array): the synced force sell’s cart item.

Normal force sells aren’t affected, because they don’t follow the main product’s quantity.

### wc\_force\_sell\_disallow\_no\_stock

Filters whether the main product is taken back out of the cart when one of its linked products can’t be added, for example because it’s out of stock. Default `true`. Return `false` to let the main product stay in the cart on its own.

### wc\_force\_sell\_show\_price

Filters whether the product page note shows each linked product’s price. Default `true`.

- `$show_price` (bool)
- `$product` (WC\_Product): the product being viewed.

### wc\_force\_sell\_product\_template\_message

Filters the text above the list of linked products on the product page. Default: `<p> This will also add the following products to your cart:</p>`.

- `$message` (string): HTML, passed through `wp_kses_post()`.
- `$product` (WC\_Product): the product being viewed.
- `$force_sells` (WC\_Product\[\]): the linked products.
- `$show_price` (bool)

### wc\_force\_sell\_show\_item\_notices

Filters whether a synced force sell gets its own "added to your cart" notice. Default `false`, which lists synced force sells in the main product’s added to cart message ("Also added: …"). Return `true` to show a separate notice for the synced force sell instead: "\[Linked product\] was added to your cart because you added \[main product\]." Available from version 2.0.6.

- `$show_notice` (bool): whether to show a separate notice for this force sell.
- `$forced_product` (WC\_Product): the synced force sell.
- `$product` (WC\_Product): the main product.
- `$cart_item_key` (string): the main product’s cart item key.

It runs only for synced force sells that were added successfully. Normal force sells never get a notice.

## Recipes

### Add one of each linked product, whatever quantity is bought

```
// Add each linked product at quantity 1, however many of the main product are added.
add_filter( 'wc_force_sell_add_to_cart_product', function( $params ) {
	$params['quantity'] = 1;
	return $params;
} );

// Keep synced force sells at quantity 1 when the main product's quantity changes.
add_filter( 'wc_force_sell_update_quantity', function( $quantity, $cart_item ) {
	return $quantity > 0 ? 1 : 0;
}, 10, 2 );
```

The second filter returns 0 when the main product is removed, so its synced force sells are removed with it.

On the cart block, also return 1 from `wc_force_sell_product_cart_quantity` so the Store API’s quantity limits match:

```
add_filter( 'wc_force_sell_product_cart_quantity', function() {
	return 1;
} );
```

### Let the main product in when a linked product can’t be added

```
add_filter( 'wc_force_sell_disallow_no_stock', '__return_false' );
```

The shopper still sees WooCommerce’s message for the linked product, but the main product stays in the cart.

### Hide prices in the product page note

```
add_filter( 'wc_force_sell_show_price', '__return_false' );
```

### Change the product page note

```
add_filter( 'wc_force_sell_product_template_message', function( $message, $product ) {
	return '<p>' . esc_html__( 'Your order will also include:', 'your-text-domain' ) . '</p>';
}, 10, 2 );
```

To change the cart notices or the **Linked to** label without code, use a translation plugin; see [changing text in a plugin](/docs/changing-text-in-a-plugin/).

## Store API cart item data

On stores using the cart and checkout blocks or a headless front end, every cart item in the Store API’s cart response carries a `force-sells` entry under `extensions`:

| Field | Type | What it holds |
|---|---|---|
| `synced_ids` | integer\[\] | On a synced force sell, its main product’s synced force sell product and variation IDs; empty on other items |
| `is_synced_force_sell` | boolean | Whether this item is a synced force sell |
| `forced_by_cart_item_key` | string | The cart item key of the main product that added it, or an empty string |

The fields are read only. The cart rules themselves run on the server: the Store API reports a synced item’s minimum and maximum quantity as its main product’s quantity, and a synced item removed while its main product is in the cart is added back the next time the cart loads.

## Keep learning

- [Get started with Force Sells](/docs/get-started-with-force-sells/) (setting up force sells and synced force sells)
- [Changing text in a plugin](/docs/changing-text-in-a-plugin/) (editing the note and notices without code)
