1. Documentation
  2. Codex
  3. Snippets
  4. General Snippets

Hide other shipping methods when “Free Shipping” is available

This is a Developer level doc. If you are unfamiliar with code/templates and resolving potential conflicts, select a WooExpert or Developer for assistance. We are unable to provide support for customizations under our  Support Policy.

Overview ↑ Back to top

By default, WooCommerce will show all shipping methods that match the customer and the cart contents. This means Free Shipping will also show along with Flat Rate and other Shipping Methods. The functionality to hide all other methods and only show Free Shipping requires either custom PHP code or a plugin/extension.

If you’d like to see this feature added to WooCommerce core, visit our Ideas Board and add your vote to it. The more popular an idea becomes, the more of a priority it is for our developers to review.

Adding code ↑ Back to top

Before adding snippets, clear your WooCommerce cache. Go to WooCommerce > System Status > Tools > WooCommerce Transients > Clear transients

Add this code to your child theme’s functions.php file or via a plugin that allows custom functions to be added, such as the Code snippets plugin. Please don’t add custom code directly to your parent theme’s functions.php file as this will be wiped entirely when you update the theme.

PHP Snippet ↑ Back to top

How do I show only Free Shipping? ↑ Back to top

Hides everything but free_shipping if it’s available and is compatible with Shipping Zones.


/**
* Hide shipping rates when free shipping is available.
* Updated to support WooCommerce 2.6 Shipping Zones.
*
* @param array $rates Array of rates found for the package.
* @return array
*/
function my_hide_shipping_when_free_is_available( $rates ) {
$free = array();
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
$free[ $rate_id ] = $rate;
break;
}
}
return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );

How do I show only Local Pickup and Free Shipping? ↑ Back to top

Hides everything but free_shipping and local_pickup if it’s available and is compatible with Shipping Zones.


/**
* Hide shipping rates when free shipping is available, but keep "Local pickup"
* Updated to support WooCommerce 2.6 Shipping Zones
*/
function hide_shipping_when_free_is_available( $rates, $package ) {
$new_rates = array();
foreach ( $rates as $rate_id => $rate ) {
// Only modify rates if free_shipping is present.
if ( 'free_shipping' === $rate->method_id ) {
$new_rates[ $rate_id ] = $rate;
break;
}
}
if ( ! empty( $new_rates ) ) {
//Save local pickup if it's present.
foreach ( $rates as $rate_id => $rate ) {
if ('local_pickup' === $rate->method_id ) {
$new_rates[ $rate_id ] = $rate;
break;
}
}
return $new_rates;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );

Show only free shipping in all states except… ↑ Back to top

Show only free shipping in all states except the exclusion list. Hide free shipping if the customer is in one of the states listed:


/**
* Hide ALL shipping options when free shipping is available and customer is NOT in certain states
*
* Change $excluded_states = array( 'AK','HI','GU','PR' ); to include all the states that DO NOT have free shipping
*/
add_filter( 'woocommerce_package_rates', 'hide_all_shipping_when_free_is_available' , 10, 2 );
/**
* Hide ALL Shipping option when free shipping is available
*
* @param array $available_methods
*/
function hide_all_shipping_when_free_is_available( $rates, $package ) {
$excluded_states = array( 'AK','HI','GU','PR' );
if( isset( $rates['free_shipping'] ) AND !in_array( WC()->customer->shipping_state, $excluded_states ) ) :
// Get Free Shipping array into a new array
$freeshipping = array();
$freeshipping = $rates['free_shipping'];
// Empty the $available_methods array
unset( $rates );
// Add Free Shipping back into $avaialble_methods
$rates = array();
$rates[] = $freeshipping;
endif;
if( isset( $rates['free_shipping'] ) AND in_array( WC()->customer->shipping_state, $excluded_states ) ) {
// remove free shipping option
unset( $rates['free_shipping'] );
}
return $rates;
}

Is there a plugin available for this? ↑ Back to top

Yes, you can also use this free plugin instead of the first two snippets: https://wordpress.org/plugins/wc-hide-shipping-methods

Enable Shipping Methods on a per Class / Product Basis, split orders, or other scenarios? ↑ Back to top

Need more flexibility? Take a look through our premium Shipping Method extensions.

WooCommerce - the most customizable eCommerce platform for building your online business.

  • 30 day money back guarantee
  • Support teams across the world
  • Safe & Secure online payment