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.
add_to_cart?string
A successful add to cart opens the drawer. Legacy aliases both, drawer, popup and bar are converted to this.
stringlauncher?string
The drawer opens only from a launcher or your own code. Legacy aliases manual and none are converted to this.
stringAny 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
httporhttpsURL 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 ).
$item?array
CartPops' presentation row for this line. Return it with your changes.
array$cart_item?array
The raw WooCommerce cart item, including your own custom keys.
array$cart_key?string
The exact WooCommerce cart item key.
stringThe 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.
name?string
Replaces the product name. Text only, tags are stripped. Up to 500 bytes. Cannot be empty.
stringshort_description?string
Replaces the short description. Text only. Up to 2,000 bytes.
stringvariationSummary?string
Replaces the variation summary. Text only. Up to 1,000 bytes.
stringextraLines?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.
array<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.
array<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.
cartpops_powered_by_link
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.
mode?"icon" | "text" | "text_icon"
What the button shows.
"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.
stringIf 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.
$attributes?array
The launcher attributes built from the Launcher > Navigation menu launcher (legacy) settings. Listed below.
array$item?object
The WordPress menu item. Use its classes or title to target a specific item.
object$item_output?string
The original markup of the menu item, before replacement.
stringicon?"cart" | "bag" | "basket"
The icon. V1 cpops-icon-* names map to cart or bag. Any other value falls back to the saved setting.
"cart" | "bag" | "basket"indicator?"none" | "bubble" | "plain"
How the item count is shown.
"none" | "bubble" | "plain"showCount?bool
False forces indicator to none. An indicator of none forces this to false.
boolshowTotal?bool
Show the cart total next to the icon.
boolhideEmpty?bool
Hide the whole launcher while the cart is empty.
boolhideIndicatorEmpty?bool
Hide only the count while the cart is empty.
boolpresentation?"inline"
Always reset to inline. You cannot make a menu launcher floating.
"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
httporhttpsURL. CartPops reduces it to scheme, host and port and compares it exactly.https://www.example.comandhttps://example.comare different origins. - The check applies to requests that send an
OriginorRefererheader, 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/prefixin CIDR form, for IPv4 or IPv6. The prefix must be at least 1 and no larger than the address size (32 or 128). Use203.0.113.7/32for a single address, not a bare IP. - At most 32 entries.
- Only
X-Forwarded-Foris read. Other headers such asCF-Connecting-IPare 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-Forheader 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;
} );