Configuration
Pair stores its settings in the pair_settings option. The settings page is under WooCommerce > Pair recommendations and requires the manage_woocommerce capability. Settings are grouped in four cards: Product page, Cart, Recently viewed and Display, below the master switch.
Settings reference
Section titled “Settings reference”| Setting (screen label) | Key | Default | Effect |
|---|---|---|---|
| Enable Pair on the storefront | enabled |
on | Master switch. When off, Pair registers no storefront hooks and no shortcodes, so nothing renders. |
| Product page: Show “You may also like” | show_on_single |
on | Renders recommendations on product pages. |
| Product page: How to choose products | single_strategy |
related |
Strategy for the product-page block. |
| Product page: Heading | single_heading |
blank | Blank uses the translated default “You may also like”. |
| Replace WooCommerce related products | replace_related |
on | Hides WooCommerce’s own “Related products” so the page shows one block, not two. Only applies while the product-page block is on. |
| Cart: Show cross-sell suggestions | show_on_cart |
on | Renders recommendations under the cart. |
| Cart: How to choose products | cart_strategy |
related |
Strategy for the cart block. |
| Cart: Heading | cart_heading |
blank | Blank uses “Add these to your order”. |
| Show recently viewed products | show_recently_viewed |
on | Enables the separate recently viewed block. |
| Recently viewed: On product pages | recently_on_single |
on | Shows the recently viewed block on product pages. |
| Recently viewed: On the cart | recently_on_cart |
off | Shows the recently viewed block on the cart. |
| Recently viewed: Heading | recently_heading |
blank | Blank uses “Recently viewed”. |
| Products per block | count |
3 | Clamped to 1-12. |
| Columns | columns |
3 | Clamped to 1-6. |
| Only recommend products that are in stock | in_stock_only |
on | Excludes products whose stock status is not “in stock”, in every block and shortcode. |
Headings are resolved when the block renders and are never written to the option, so a blank heading follows the site language.
Where each block renders
Section titled “Where each block renders”| Placement | Hook | Priority | Condition |
|---|---|---|---|
| Product-page recommendations | woocommerce_after_single_product_summary |
15 | show_on_single |
| Recently viewed on product pages | woocommerce_after_single_product_summary |
16 | show_recently_viewed and recently_on_single |
| Cart recommendations (classic cart) | woocommerce_after_cart |
10 | show_on_cart |
| Recently viewed on the cart (classic cart) | woocommerce_after_cart |
10 | show_recently_viewed and recently_on_cart |
| Cart block | render_block_woocommerce/cart filter, output appended after the block |
10 | either cart placement on |
WooCommerce prints its related products on woocommerce_after_single_product_summary at priority 20, so Pair’s block sits above where they were. With Replace WooCommerce related products on, Pair removes woocommerce_output_related_products from that hook and, for block themes, empties the Related Products block and any Product Collection block set to “Related” on product pages.
On a page using the Cart block, a placement is not appended when the page content already contains its shortcode ([pair_recommendations] or [pair_recently_viewed]), so it never shows twice.
The stylesheet loads in the head only on product and cart pages; shortcodes, Elementor widgets and the Cart block append enqueue it when they render.
Strategies
Section titled “Strategies”| Value | Screen label | Picks |
|---|---|---|
related |
Same category (by popularity) | Products in the categories of the seed products, ordered by total sales. |
tags |
Shared tags | Products sharing a product tag with the seed products, ordered by total sales. |
bestsellers |
Best sellers | Top sellers by total sales, within the seed products’ categories when they have any, otherwise store-wide. |
newest |
Newest products | Most recently published products. |
recently |
Recently viewed by the shopper | Products from the shopper’s recently viewed list. |
The seed is the current product on a product page and the products in the cart on the cart. Seed products are never recommended. Only published products visible in the catalog are picked.
When a strategy finds fewer products than Products per block, the list is topped up with the newest products. The recently viewed block is the exception: it shows only what the shopper actually viewed and does not render at all for a first-time visitor.
Recently viewed tracking
Section titled “Recently viewed tracking”Viewing a product page stores its ID in the pair_recently_viewed cookie: most recent first, at most 20 IDs, kept for 30 days, SameSite=Lax, and Secure on HTTPS. Nothing is stored in the database. The product being viewed is left out of its own recently viewed block.
Shortcodes
Section titled “Shortcodes”[pair_recommendations][pair_recommendations strategy="bestsellers" count="4" columns="4"][pair_recently_viewed count="4" columns="4"][pair_recommendations] attributes:
| Attribute | Default | Range |
|---|---|---|
strategy |
the Product page strategy | related, tags, bestsellers, newest, recently; anything else falls back to related |
count |
Products per block | 1-12 |
columns |
Columns | 1-6 |
heading |
the Product page heading | text |
[pair_recently_viewed] takes count, columns and heading (default: the Recently viewed heading).
On a product page, [pair_recommendations] uses the current product as the seed. Elsewhere it uses the cart contents. [pair_recently_viewed] always reads the recently viewed cookie. Both shortcodes respect Only recommend products that are in stock, and render nothing when the list is empty.
The grid is rendered through WooCommerce’s content-product template part, so it inherits the active theme’s product card markup.
Developer hooks
Section titled “Developer hooks”pair/recommendations filters the products of the automatic product-page and cart blocks before they render. Arguments: $products (array of WC_Product), $context (single or cart) and $seed_ids (the product IDs the picks are for). The shortcodes and the recently viewed block do not run this filter.
add_filter( 'pair/recommendations', function ( array $products, string $context, array $seed_ids ): array { if ( 'cart' !== $context ) { return $products; } // Drop one product from cart suggestions. return array_values( array_filter( $products, fn ( $p ) => 123 !== $p->get_id() ) );}, 10, 3 );pair/booted fires once Pair has registered its services, with the plugin instance. Pair Pro hooks in here.
Storage and uninstall
Section titled “Storage and uninstall”Pair stores only:
pair_settingspair_db_version
The uninstall routine removes both options and the per-user pair_pro_banner_dismissed meta. It does not create custom database tables. The recently viewed cookie lives in the shopper’s browser and expires on its own.