Skip to content
CartPops Docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

PHP filters

Every cartpops_ filter in CartPops V2 with its signature, accepted values, fallback rules and an example.

CartPops V2 has 15 public filters. Most of them validate what you return and fall back to a safe value, silently, when the value is not accepted. If a filter seems to have no effect, check the accepted values below first.

Filter Purpose Edition
cartpops_add_to_cart_trigger Decide whether adding to the cart opens the drawer. Free and Pro
cartpops_checkout_button_url Change the checkout button destination. Free and Pro
cartpops_empty_cart_button_url Change the Continue shopping destination in the empty cart. Free and Pro
cartpops_cart_item_data Add text rows or plugin data to a cart line. Free and Pro
cartpops_powered_by_link Change the Powered by link destination. Free and Pro
cartpops_secondary_btn_classes Add CSS classes to the secondary action button. Pro
cartpops_pro_recommendation_button_presentation Change the recommendation add button label and style. Pro
cartpops_store_api_cart_extension_data and _schema Add data to the cartpops Store API namespace. Free and Pro
cartpops_menu_launcher_attributes Change a menu launcher’s attributes. Free and Pro
cartpops_custom_css_style_dependencies Control which stylesheets load before Custom CSS. Free and Pro
cartpops_render_drawer Stop CartPops adding the drawer to the footer. Free and Pro
cartpops_rest_allowed_origins Allow another origin to call the cartpops/v1 routes. Free and Pro
cartpops_rest_trusted_proxy_cidrs Tell the rate limiter which proxies to trust. Free and Pro
cartpops_elementor_widget_cart_is_hidden Hide the CartPops Elementor widget. Pro

Filters that are not listed here are internal. The cartpops_secondary_btn_attributes filter from V1 is not supported in V2.

cartpops_add_to_cart_trigger

apply_filters( 'cartpops_add_to_cart_trigger', string $trigger ): string

Receives the Open drawer on setting (Advanced > General) when the drawer renders. Return add_to_cart to open the drawer after a successful add to cart, or launcher to open it only when the shopper uses a launcher.

PropType
add_to_cart?string

A successful add to cart opens the drawer. Legacy aliases both, drawer, popup and bar are converted to this.

Typestring
launcher?string

The drawer opens only from a launcher or your own code. Legacy aliases manual and none are converted to this.

Typestring

Any other result falls back to launcher: non-strings, values longer than 32 characters, and values that differ in case or whitespace (Add_To_Cart, add_to_cart). The filter runs when the drawer is rendered, so a full-page cache keeps whatever value the cached page was built with.

// Keep the drawer closed on the cart and checkout pages.
add_filter( 'cartpops_add_to_cart_trigger', static function ( $trigger ) {
	return ( is_cart() || is_checkout() ) ? 'launcher' : $trigger;
} );

cartpops_checkout_button_url

apply_filters( 'cartpops_checkout_button_url', string $url ): string

Receives the WooCommerce checkout URL. The result becomes the checkout button link, and it is kept when the drawer updates in the browser.

add_filter( 'cartpops_checkout_button_url', static function ( string $url ): string {
	return add_query_arg( 'source', 'drawer', $url );
} );

The same rules apply to both URL filters. Return a plain URL, not HTML. CartPops accepts a result that is:

  • an absolute http or https URL with a host, or
  • a root-relative site URL that starts with a single slash, such as /shop/.

CartPops rejects and falls back to the original WooCommerce URL for a bare relative path such as shop, an empty string, a non-string, a protocol-relative URL (//example.com), a URL with a username or password, a URL with spaces, control characters or a backslash, any other scheme (javascript:, mailto:), and a URL longer than 8,192 characters.

cartpops_empty_cart_button_url

apply_filters( 'cartpops_empty_cart_button_url', string $url ): string

Receives the WooCommerce shop page URL. The result becomes the Continue shopping link in the empty cart. Opening the link closes the drawer and then navigates. The same URL rules as the checkout filter apply.

add_filter( 'cartpops_empty_cart_button_url', static function (): string {
	return '/collections/best-sellers/';
} );

cartpops_cart_item_data

apply_filters( 'cartpops_cart_item_data', array $item, array $cart_item, string $cart_key ): array

Adjust how one cart line is presented in the drawer. This is the V2 replacement for V1’s per-item HTML and class hooks. Add the callback with three accepted arguments: add_filter( 'cartpops_cart_item_data', $callback, 10, 3 ).

PropType
$item?array

CartPops' presentation row for this line. Return it with your changes.

Typearray
$cart_item?array

The raw WooCommerce cart item, including your own custom keys.

Typearray
$cart_key?string

The exact WooCommerce cart item key.

Typestring

The filter runs every time CartPops rebuilds its cart state in PHP: the first render, add-to-cart fragments, CartPops cart reads and changes, and WooCommerce Store API cart responses. The result travels to the browser, so it stays in place when the shopper changes quantities or removes lines. Do not keep per-request state in the callback.

Fields you can change

CartPops accepts only these five fields from your return value. It validates each one on its own. If one field is invalid, only that field falls back.

PropType
name?string

Replaces the product name. Text only, tags are stripped. Up to 500 bytes. Cannot be empty.

Typestring
short_description?string

Replaces the short description. Text only. Up to 2,000 bytes.

Typestring
variationSummary?string

Replaces the variation summary. Text only. Up to 1,000 bytes.

Typestring
extraLines?array<array{label: string, value: string}>

Up to 20 rows shown under the product name. Each row has exactly the keys label and value. A label is required and up to 160 bytes. A value is up to 1,000 bytes. Tags and control characters are stripped. If any row is invalid the whole field is rejected.

Typearray<array{label: string, value: string}>
customPresentation?array<string, mixed>

Plain data for your own client code. CartPops never renders it. Keys must start with a letter and use only letters, numbers, underscore, hyphen or dot, up to 64 bytes. Up to 16 entries per level, 4 levels deep, 64 values and 8,192 bytes of JSON. Strings are plain text up to 1,024 bytes.

Typearray<string, mixed>

Use a unique key for your plugin inside customPresentation, such as my_plugin, so plugins do not overwrite each other.

extraLines already holds the rows that other plugins add with WooCommerce’s own woocommerce_get_item_data filter. Append to it to keep those rows. Replace it to drop them. For a plain label and value row, woocommerce_get_item_data also works and is picked up the same way.

Fields you receive but cannot change

CartPops restores every other field, including any that a future version adds. The row you receive includes key, id, product_id, permalink, quantity, isOnSale, images, prices, formattedPrice, formattedRegularPrice and the fields that control quantity and removal. A callback cannot change the cart key used by remove and quantity requests, prices, product identity, whether a line is locked, or link and image URLs. Returning HTML, directives, classes or scripts is not supported.

add_filter(
	'cartpops_cart_item_data',
	static function ( array $item, array $cart_item, string $cart_key ): array {
		if ( empty( $cart_item['my_engraving'] ) ) {
			return $item;
		}

		$item['extraLines'][] = array(
			'label' => __( 'Engraving', 'my-plugin' ),
			'value' => (string) $cart_item['my_engraving'],
		);
		$item['customPresentation']['my_plugin'] = array(
			'cartItemKey'  => $cart_key,
			'personalized' => true,
		);

		return $item;
	},
	10,
	3
);

Over the Store API, the presentation of up to 100 cart lines and 1 MiB of data per response is carried. If a cart exceeds that, CartPops drops the optional presentation for that response and keeps the cart usable. See Store API and REST for where the data appears.

apply_filters( 'cartpops_powered_by_link', string $url ): string

Receives the Freemius partner URL for the Powered by CartPops link, which has the form https://r.freemius.com/7061/{code}/. It runs only when Show the CartPops partner link is on and a valid partner code is saved (Advanced settings). Otherwise the link is not shown and the filter does not run.

Return a complete http or https URL with a host. CartPops falls back to the original URL for a non-string, a URL with credentials, spaces, control characters or a backslash, an unsupported scheme, or a URL longer than 2,048 characters. Root-relative URLs are not accepted here.

add_filter( 'cartpops_powered_by_link', static function (): string {
	return 'https://example.com/go/cartpops';
} );

cartpops_secondary_btn_classes

apply_filters( 'cartpops_secondary_btn_classes', array $classes, string $mode ): array

Receives the list of CSS classes CartPops puts on the secondary action button, and the action mode: continue_shopping, view_cart or custom_url. You can add classes. You cannot remove CartPops’ own classes, and you cannot change the label, destination, element type or behavior.

The result must be a list of at most 16 strings. Each class must be one CSS identifier that starts with a letter or underscore and has at most 64 letters, digits, underscores or hyphens. Duplicates are removed. If anything is wrong, such as a bad token, a non-list or too many entries, CartPops discards your whole result and uses its own classes.

add_filter( 'cartpops_secondary_btn_classes', static function ( array $classes, string $mode ): array {
	$classes[] = 'my-secondary-button';
	$classes[] = 'my-secondary-button--' . str_replace( '_', '-', $mode );
	return $classes;
}, 10, 2 );

cartpops_pro_recommendation_button_presentation

apply_filters( 'cartpops_pro_recommendation_button_presentation', array $presentation ): array

Receives the recommendation add button presentation, and runs once while the Pro drawer renders.

PropType
mode?"icon" | "text" | "text_icon"

What the button shows.

Type"icon" | "text" | "text_icon"
text?string

The label for the text modes. Tags are stripped and spaces are collapsed. Text longer than 80 characters is cut to 80. Empty text, control characters, directional characters and invalid UTF-8 are rejected.

Typestring

If the result is not an array, has an unknown mode or has unusable text, CartPops uses the hard defaults, icon and Add. It does not use the value saved in the settings. The filter changes only the look of the button. It cannot change which products are recommended or what the button does. Variable products keep their Select options link.

add_filter( 'cartpops_pro_recommendation_button_presentation', static function ( array $presentation ): array {
	$presentation['mode'] = 'text_icon';
	$presentation['text'] = __( 'Add this item', 'my-plugin' );
	return $presentation;
} );

cartpops_store_api_cart_extension_data

apply_filters( 'cartpops_store_api_cart_extension_data', array $data ): array

Adds data to the cartpops namespace of the WooCommerce Store API cart response. It runs on every Store API cart response, including WooCommerce’s own add to cart, so keep the callback fast. Return the complete array, with your keys added.

add_filter( 'cartpops_store_api_cart_extension_data', static function ( array $data ): array {
	$data['my_plugin'] = array(
		'gift_wrap_available' => true,
	);
	return $data;
} );

The result is accepted only if the whole array is bounded JSON data. Allowed values are null, booleans, integers, finite numbers, valid UTF-8 strings, lists and maps with string keys. Not allowed: objects, resources, recursive arrays and non-finite numbers. The limits are 8 levels deep, 512 values, 128 entries per list or map, 128 bytes per key, 8,192 bytes per string and 65,536 bytes of JSON. The top level must be a map, not a list.

If any rule is broken, CartPops discards the whole result and uses its own baseline. CartPops always restores its own coupons, item_presentations and optional_locked_keys keys after your filter runs, so you cannot change or remove them. Avoid the keys drawer_config and launcher as well, which CartPops also uses.

cartpops_store_api_cart_extension_schema

apply_filters( 'cartpops_store_api_cart_extension_schema', array $schema ): array

The JSON schema for the data above. Add a schema entry for each key you add to the data. The same bounds and fallback rules apply, and CartPops restores its own schema for the three reserved keys.

add_filter( 'cartpops_store_api_cart_extension_schema', static function ( array $schema ): array {
	$schema['my_plugin'] = array(
		'description' => 'My plugin cart data.',
		'type'        => 'object',
		'readonly'    => true,
	);
	return $schema;
} );

cartpops_menu_launcher_attributes

apply_filters( 'cartpops_menu_launcher_attributes', array $attributes, object $item, string $item_output ): array

Runs for each classic navigation menu item that has the cpops-cart-menu-item CSS class, just before CartPops replaces the item with an inline launcher. It does not run for other menu items or for the Navigation block.

PropType
$attributes?array

The launcher attributes built from the Launcher > Navigation menu launcher (legacy) settings. Listed below.

Typearray
$item?object

The WordPress menu item. Use its classes or title to target a specific item.

Typeobject
$item_output?string

The original markup of the menu item, before replacement.

Typestring
PropType
icon?"cart" | "bag" | "basket"

The icon. V1 cpops-icon-* names map to cart or bag. Any other value falls back to the saved setting.

Type"cart" | "bag" | "basket"
indicator?"none" | "bubble" | "plain"

How the item count is shown.

Type"none" | "bubble" | "plain"
showCount?bool

False forces indicator to none. An indicator of none forces this to false.

Typebool
showTotal?bool

Show the cart total next to the icon.

Typebool
hideEmpty?bool

Hide the whole launcher while the cart is empty.

Typebool
hideIndicatorEmpty?bool

Hide only the count while the cart is empty.

Typebool
presentation?"inline"

Always reset to inline. You cannot make a menu launcher floating.

Type"inline"

Booleans accept true, false, 1, 0, "1", "0" and the strings true, false, yes, no, on and off. Any value that does not validate falls back to the saved menu launcher setting. A result that is not an array uses all saved settings.

add_filter( 'cartpops_menu_launcher_attributes', static function ( array $attributes, object $item ): array {
	if ( in_array( 'my-header-cart', (array) $item->classes, true ) ) {
		$attributes['icon']      = 'basket';
		$attributes['showTotal'] = true;
	}
	return $attributes;
}, 10, 2 );

cartpops_custom_css_style_dependencies

apply_filters( 'cartpops_custom_css_style_dependencies', string[] $handles ): string[]

Your Custom CSS (Advanced > General > Custom CSS) is added as an inline stylesheet that depends on the CartPops drawer stylesheet. This filter lists the style handles that the Custom CSS depends on, which controls what loads before it. It runs only when Custom CSS is not empty and CartPops is enabled.

The default is array( 'cartpops-cart-drawer-style' ). CartPops pins that handle first, so you cannot remove it. In CartPops Pro, the Pro plugin also uses this filter to add its own handle, so append to the array instead of replacing it.

CartPops ignores any entry that is not a string, is longer than 100 characters, does not match a-z, 0-9, ., _ and - (starting with a letter or digit), or is already in the list. Anything that is not an array leaves only the shared handle.

// Load Custom CSS after the launcher stylesheet and a theme stylesheet.
add_filter( 'cartpops_custom_css_style_dependencies', static function ( $handles ) {
	$handles   = is_array( $handles ) ? $handles : array();
	$handles[] = 'cartpops-cart-launcher-style';
	$handles[] = 'my-theme-style';
	return $handles;
} );

cartpops_render_drawer

apply_filters( 'cartpops_render_drawer', bool $render ): bool

Decides whether CartPops adds its drawer to wp_footer. The default is true. Any falsy result turns the automatic drawer off.

The filter only affects the automatic footer drawer. It is skipped when CartPops is switched off, and when a Cart Drawer block is already printed by a template or page, because that block is used instead. It does not remove the launcher. If you turn the drawer off, also turn off Show floating cart launcher on the Launcher screen, or its button will do nothing.

// No automatic drawer on the checkout page.
add_filter( 'cartpops_render_drawer', static function ( $render ) {
	return is_checkout() ? false : $render;
} );

cartpops_rest_allowed_origins

apply_filters( 'cartpops_rest_allowed_origins', string[] $urls ): string[]

Controls which origins can call the cartpops/v1 REST routes from a browser. The default list holds your site’s home and site URLs. Add an origin when a headless front end or a second domain on a different host needs to call the routes.

  • Each entry must be a full http or https URL. CartPops reduces it to scheme, host and port and compares it exactly. https://www.example.com and https://example.com are different origins.
  • The check applies to requests that send an Origin or Referer header, which is every browser request. A request with neither header, such as one from a server, passes this check. The other protections still apply.
  • If the origin and referrer both exist, they must agree.
  • A rejected request gets HTTP 403 with the code cartpops_forbidden_origin.
  • Matching origins also get CORS headers that allow credentials.

This filter applies only to cartpops/v1. It does not change WooCommerce Store API requests.

add_filter( 'cartpops_rest_allowed_origins', static function ( $urls ) {
	$urls   = is_array( $urls ) ? $urls : array();
	$urls[] = 'https://shop.example.com';
	return $urls;
} );

cartpops_rest_trusted_proxy_cidrs

apply_filters( 'cartpops_rest_trusted_proxy_cidrs', string[] $cidrs ): string[]

CartPops rate limits its write routes per client IP address and per visitor. By default it uses the connection’s own address. Behind a CDN or reverse proxy, that address is the proxy’s, so every visitor shares one limit and shoppers can start to see HTTP 429 responses. Return the networks of the proxies you trust, and CartPops will then read the visitor’s address from the X-Forwarded-For header.

  • Each entry is address/prefix in CIDR form, for IPv4 or IPv6. The prefix must be at least 1 and no larger than the address size (32 or 128). Use 203.0.113.7/32 for a single address, not a bare IP.
  • At most 32 entries.
  • Only X-Forwarded-For is read. Other headers such as CF-Connecting-IP are ignored.
  • When the connection comes from a trusted proxy, CartPops reads the header and uses the right-most address that is not itself a trusted proxy. The header must be present, at most 1,024 bytes, hold at most 10 addresses, and every entry must be a valid IP.
  • Anything outside your list is treated as an ordinary visitor and its X-Forwarded-For header is ignored.
add_filter( 'cartpops_rest_trusted_proxy_cidrs', static function (): array {
	return array(
		'203.0.113.0/24',
		'2001:db8::/32',
	);
} );

cartpops_elementor_widget_cart_is_hidden

apply_filters( 'cartpops_elementor_widget_cart_is_hidden', bool $hidden ): bool

Receives false. Return true to make the widget print nothing on the current request. The filter takes no widget or page argument, so check the page yourself.

// Hide the Elementor cart widget on the checkout page.
add_filter( 'cartpops_elementor_widget_cart_is_hidden', static function ( $hidden ) {
	return is_checkout() ? true : $hidden;
} );

Was this page helpful?