We’ve got an Ask Jilt question today about WooCommerce free shipping from Andrea:
Can I hide the other shipping options when there are free shipping choices? I tried the snippet in the WooCommerce doc page but I think it doesn’t work for me because I’m not using the “Free Shipping” one in my zone, but my shipping is still free because I use shipping classes.
This one is an interesting question, and we can definitely hide other rates when WooCommerce free shipping is available, regardless of what kind of shipping method it is.
The document Andrea’s referring to is this guide to hiding other methods if free shipping is available. However, the snippet in that document is indeed pretty specific.
That code looks for the free_shipping
rate — or those that you add to a zone with the “Free Shipping” type (ie, the ones you can set a cart threshold for, or use coupons to enable). However, this does not look for other sorts of free rates, like a free flat rate.
The good news here is that we can use the same hook that snippet uses — the woocommerce_package_rates
filter — to help us modify which rates are available to the customer.
Let’s start with the code here, and then show you what it will do. If you’re not sure how to add custom code to your site, be sure to read this guide, as this change requires a snippet.
So the filter I mentioned gives us access to an array of rates in the cart. We can access these rates, check the cost of each rate, then only spit back out the free ones. If there are no free ones, then we can show the original rates we started with.
Here’s a look at that snippet:
<?php // only copy if needed
/**
* Hides any non-free shipping methods if free shipping is available
*
* @param array $rates array of \WC_Shipping_Rate objects that apply to the cart
* @return array - the updated available rates
*/
function sww_wc_hide_non_free_shipping( $rates ) {
$free_rates = array();
foreach ( $rates as $rate_id => $rate ) {
if ( 0 === (int) $rate->cost ) {
$free_rates[ $rate_id ] = $rate;
// uncomment this `break;` if you only want to show the first free rate
// break;
}
}
return ! empty( $free_rates ) ? $free_rates : $rates;
}
add_filter( 'woocommerce_package_rates', 'sww_wc_hide_non_free_shipping' );
Now notice the part I have commented out — that may or may not apply to you, so let’s take a look at what this code will do, and then you can determine whether you need it or not.
If you have the “Free shipping” method in use in your store, you could have used the documentation that WooCommerce has provided. However, our snippet will still work just fine with that since we’re checking the cost of the rate, not the kind of method it is.
If you had free shipping available for your product, it would be shown along with all possible rates in the cart (though it’s at least selected by default):
However, with our snippet added, this will now only show the “Free Shipping” rate when it’s available:
If free shipping were not available, the other rates would be shown normally.
Now what if you have a free rate, but it’s a different kind of rate, like a flat rate? I’ve seen merchants do this with shipping classes specifically, as outlined in this post.
Our snippet will work for this set up, too. By default, all available rates for the zone are shown:
With our snippet, even though this is a “Flat Rate” method, because it costs $0, we recognize it as a free method, and hide the others.
Now for the final set up with our snippet. If you have multiple ways of achieving free shipping, like both flat rates and free shipping methods, these could conceivably be shown together in the cart shipping options by default.
Our snippet will currently recognize that both of these rates are free, and will show both of them to the customer. This might be handy if you have more descriptive “free rate” labels than I do and there are differences between them ๐
If you only want to show one of your WooCommerce free shipping rates at any given time, you can uncomment out the final break;
in my snippet — delete the two leading slashes. This will tell the code to stop after it finds the first free shipping method and use that for the customer.
That’s a wrap! Hope this helps you with your WooCommerce free shipping set up Andrea ๐
Thanks for sharing, very handy.
Very useful and it works great but… how to create exceptions for some shipping methods?
For example, if you have, among your shipping methods, the “pick up in store” option (that is “de facto” a free shipping method), and you want this option always visible.