Your WooCommerce products can have upsells assigned to them so that you can encourage customers to buy different versions or more expensive products while visiting your product page. You can add these under Product Data > Linked Products while editing a product, and the upsells will be shown at the end of your product description.

However, most times this is at the bottom of your product page. What if customers don’t end up scrolling all of the way? They won’t see your more expensive or profitable products that can drive increased revenue, as they could add the current product to the cart without ever seeing upsells.

To combat this, you could move the location of your upsells on the product page. The easiest way to move upsells is to put them in a widget, then remove them from the product page if the widget is used, so we’ll take a look at using this method to move upsells first.

Create a WooCommerce Upsells Widget

In this example, we’ll use a widget to show upsells, then hide the original upsells on the product page if the widget is active. If you want some more in-depth details on creating widgets, we’ve written two tutorials in our “Learn to build WooCommerce plugins” series:

Since those two articles focus on the details of building a widget, we’ll only focus on the relevant functions to our upsells here.

First, the widget function will need to output the upsells when it’s used. This is definitely easy enough to do, as WooCommerce includes a template function for this: woocommerce_upsell_display()

public function widget( $args, $instance ) {
    
    // Only show this if we're looking at a product page
    if ( ! is_singular( 'product' ) ) {
        return;
    }

    global $product;

    // bail if the product has no upsells before we output anything
    if ( ! $product->get_upsells() ) {
        return;
    }   
        
    // get the widget configuration
    $title = $instance['title'];
        
    echo $args['before_widget'];
        
    if ( $title ) {
        echo $args['before_title'] . wp_kses_post( $title ) . $args['after_title'];
    }
        
    // Show the product's upsells
    woocommerce_upsell_display();
        
    echo $args['after_widget'];
}

That’s the meat of our widget already 🙂 Now we have to remove the original upsell display if this widget is in use. The is_active_widget() check is our friend here, and we can remove the upsells from the bottom of the product page if this widget is in use.

public function remove_product_upsells() {
    if ( is_singular( 'product' ) && is_active_widget( false, false, $this->id_base ) ) {
        remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
    }
}

That’s the basic gist of our upsells widget: remove the old upsells, and add our new ones where we want them. However, I’ll take two final steps to clean up the display of my upsells widget.

First, I’ll modify the number of columns in the upsells display to use two columns:

public function change_upsell_columns( $args ) {
  if ( is_singular( 'product' ) && is_active_widget( false, false, $this->id_base ) ) {
    $args['columns'] = 2;
  }
  return $args;
}

Second, I’ll add some CSS to adjust the column widths appropriately so they take up the full widget space without looking smooshed.

public function modify_product_upsells_styles() {
  if ( is_singular( 'product' ) && is_active_widget( false, false, $this->id_base ) ) {
    echo '<style>
      .woocommerce .widget_wc_upsells ul.products li.product,
      .woocommerce-page .widget_wc_upsells ul.products li.product {
        width: 48%;
        margin-top: 1em;
      }
    </style>';
  }
}

Now my upsells will also look like they belong there when used in a widget, as styles will be adjusted for the widget space.

You can view the complete code here — click “Download Zip” and install this as a plugin if desired, or checkout the gist to modify it further for your own plugin.

The Results: A WooCommerce Upsells Widget

Let’s have a look at a comparison. When the upsells are originally displayed, they’ll be shown below the main description.

WooCommerce Upsells regular display

Upsells: regular display

Now I’ll install my upsells widget plugin, and add it to my sidebar.

WooCommerce Upsells widget

New Upsells widget

Now that this widget is active, my upsells are removed from the bottom of the product page, and displayed in 2 columns in the sidebar instead.

WooCommerce Upsells in widget

Upsells in widget

Create an Upsells Shortcode

You could also create an upsells shortcode, but there’s no easy way to know if a shortcode is “active” like there is with a widget.

As a result, we’ll go more in-depth with this next week in a for-developers tutorial, as it makes a good example of using a class member in a plugin. This would let you use the shortcode (for example) in a new product tab or elsewhere on the product page.

Published by Beka Rice

Beka leads product direction for SkyVerge and technical documentation. She spends a lot of time on research and interviews, but likes to write so she has an excuse to spend more time jamming out to anything from The Clash to Lady Gaga.

12 Comments

  1. Avatar

    Hi Beka,

    thanks for another great post. Just a suggestion. It would be nice to hide the widget if no upsells are set for product(s).

    Regards,

    Boogie

  2. Avatar

    Looking forward to using this, one question, I’ve downloaded the plugin, is there a shortcode added in already, or do I need to to the last stage?

    Thanks

  3. Avatar

    Nice Idea.

    I made a plugin that do almost same. You can disable/rearrange content inside the single product page and shop page. Also, you can remove checkout fields. but it can’t display related products inside tab. It’s a great idea so I’m going to add it to my plugin. I uploaded the plugin to wordpress, so here you have the link WooEnhacer – WooCommerce Customizer if someone is interested.

  4. Avatar

    To install this as a plugin broke my page completely. Now I just get a blank page with a message: Warning: Cannot modify header information – headers already sent by (output started at…Etc.

  5. Avatar

    Hi Beka! How I could insert content like as the weight in the upsell loop? I’m sorry but English is not my first language, thank you for the tutorial!

  6. Avatar

    @Beka: The latest WooCommerce 3.0 update seems to have broken what was once a a working widget :-((
    WooCommerce System Status only reported one Template override that needing repairing – which I’ve done.
    Other than that theres no php errors in the debug log for the widget… its like its just vanished.
    Although I can see the file still in Appearance > Editor
    Any ideas on how I can debug this widget – I really liked this feature!
    Thanks in advance
    Peter

    • Avatar

      I see no issues with the current widget (just a deprecation notice in my logs), so an update isn’t likely to resolve whatever issue you’re seeing. However, I’ve updated the one deprecated function in the codebase now if you’d like to give it a go!

      • Avatar

        Hey Beka,
        Thanks for the reply – I deleted the old plugin and added the latest version & the plugin has reappeared, activated and all works fine now.
        Thanks again for the quick response!

  7. Avatar

    “linked products” tab (upsells , crosssells) not clickable in product dashboard everything.
    unable to add any related products in up-sells cross-sells.

  8. Avatar

    Hi Beka Rice

    can you help me , i show my upsell product instead of related product , how can implement this i use or plugin but i really not understand much more ,i am new in wordpress and english is not my native language

Hmm, looks like this article is quite old! Its content may be outdated, so comments are now closed.