WooCommerce: Show Shipping Rates @ Single Product Page

Here’s a way to print shipping zones and rates on the single product page, so that users know how much they’ll end up spending once they reach the Cart/Checkout and there are no “hidden” fees. Not bad for some transparency = better sales conversion rate!

In this tutorial we will first see how to get the default “WooCommerce Shipping Zones Data” and in a second snippet we will instead see how to get the info for each vendor instead.

Either way, enjoy!

Here’s the new “Shipping” section on the WooCommerce Single Product Page that gathers data from each shipping zones.

PHP Snippet: Display Shipping Zones & Methods @ WooCommerce Single Product Page (WooCommerce Plugin)

 * @snippet       Show Shipping Rates - WooCommerce Single Product
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 8
 * @community     https://businessbloomer.com/club/

add_action( 'woocommerce_after_add_to_cart_form', 'bbloomer_shipping_rates_single_product' );

function bbloomer_shipping_rates_single_product() {
   global $product;
   if ( ! $product->needs_shipping() ) return;
	$zones = WC_Shipping_Zones::get_zones();
	echo '<div><i class="fas fa-truck"></i> ' . __( 'Shipping', 'woocommerce' );
	echo '<table>';
	foreach ( $zones as $zone_id => $zone ) {
		echo '<tr><td>';
		echo $zone['zone_name'] . '</td><td>';
		$zone_shipping_methods = $zone['shipping_methods'];
		foreach ( $zone_shipping_methods as $index => $method ) {
			$instance = $method->instance_settings;
			$cost = $instance['cost'] ? $instance['cost'] : $instance['min_amount'];
			echo $instance['title'] . ' ' . wc_price( $cost ) . '<br>';
		echo '</td></tr>';
	echo '</table></div>';

Advanced Plugin: WooCommerce Shipping Calculator

The above code snippet displays all the shipping zones and options on the product page. As an alternative, I also found a plugin that lets you add the full WooCommerce shipping calculator to the product page.

WooCommerce Shipping Calculator lets customers enter their location and then displays the available shipping options. It’s a simple and flexible plugin and comes with a choice of options for where to display the calculator on the product page.

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce Visual Hook Guide: Single Product Page
    Here’s a visual hook guide for the WooCommerce Single Product Page. This is part of my “Visual Hook Guide Series“, through which you can find WooCommerce hooks quickly and easily by seeing their actual locations (and you can copy/paste). If you like this guide and it’s helpful to you, let me know in the comments! […]
  • WooCommerce: Disable Variable Product Price Range $$$-$$$
    You may want to disable the WooCommerce variable product price range which usually looks like $100-$999 when variations have different prices (min $100 and max $999 in this case). With this snippet you will be able to hide the highest price, and add a “From: ” prefix in front of the minimum price. At the […]
  • WooCommerce: Hide Price & Add to Cart for Logged Out Users
    You may want to force users to login in order to see prices and add products to cart. That means you must hide add to cart buttons and prices on the Shop and Single Product pages when a user is logged out. All you need is pasting the following code in your functions.php (please note: […]
  • WooCommerce: “You Only Need $$$ to Get Free Shipping!” @ Cart
    This is a very cool snippet that many of you should use to increase your average order value. Ecommerce customers who are near the “free shipping” threshold will try to add more products to the cart in order to qualify for free shipping. It’s pure psychology. Here’s how we show a simple message on the […]
  • WooCommerce: Weight-Based Shipping Methods
    With WooCommerce you get 3 default shipping methods: Flat Rate, Free Shipping, Local Pickup. For each one you can define a cost, however there is no way to set up some “weight” restrictions. So, what if you want to display a rate for orders below 10 kg, and another shipping rate for orders above that […]

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

24 thoughts on “WooCommerce: Show Shipping Rates @ Single Product Page

  1. Hi!

    Love your blog! I have been using several of your snippets on my projects.
    This snippet is awesome, but how can I get this to work if I have multiple shipping classes?

    Kind Regards,

    1. Hello Andree, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  2. Please tell me how to hide it on digital products? I’ve both physical and digital products. It is also visible on digital products.

    1. You’re 100% right! Check the new version please

  3. Rodolfo, thanks for the snippet.

    I’m using “WooCommerce Table Rate Shipping” from Bolder Elements.
    You code is printing shipping zones, title but all rates are being displayed as 0,00.

    Any chance to get the correct rates with your code?

    1. Hi Vinicius, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  4. This is exactly what I was looking for. So excited to find your site and this snippet.

    I tried the first code and it does show Shipping and the table below. However it shows shipping only for in-country shipping (I have two zones set up – in-country and international). And it shows 0 in the cost field even though I have defined costs for the shipping class selected for the product. Could this be because I have Dokan marketplace? Any pointers to what I might check for to get this to work?

    Using your YITH code (replacing it with dokan) didn’t work at all as I guess Dokan probably has different variables.

    1. Thanks Manish, yes, I believe the code may need to be customized to make it compatible with Dokan

  5. Hello and thank you for this.
    I have an issue though. When I add the code to functions.php I get the following error.

    Notice: Undefined index: min_amount in /var/www/webroot/stage-sneakfreakscy/wp-content/themes/shoptimizer-child-theme/functions.php on line 275
    Home Delivery €0,00

    Why is that please?

    1. Usually free shipping rates have a “min_amount” that trigger the method. If you don’t have this, the code won’t find it, and you have this “Notice” (which is nothing serious).

      If you want to fix this, you could change

      $cost = $instance['cost'] ? $instance['cost'] : $instance['min_amount'];


      $cost = $instance['cost'] ? $instance['cost'] : ( $instance['min_amount'] ? $instance['min_amount'] : 0 );
      1. Hi Rodolfo, and thanks again for all your great help.
        I tried it, and got the error
        Warning: Undefined array key “min_amount” even after changing the min -amount line
        Any idea ? Thanks again !

        1. You shouldn’t worry about warning too much – anyway, you probably need to check if the array key is set:

          $cost = isset( $instance['cost'] ) ? $instance['cost'] : ( isset( $instance['min_amount'] ) ? $instance['min_amount'] : 0 );
  6. Hi Rodolfo,
    I placed the php snippet at the bottom of my child themes functions.php file.
    But there’s nothing showing up at my product pages πŸ™

    P.s. it’s not the website which I put in my info but another website I’m working on.

    1. You don’t even see the “Shipping” title? If yes, then it’s because you’re on a custom theme and default WooCommerce hooks won’t work out of the box. Let me know

      1. Hey Rodolfo,

        I ran into this issue as well. I just did a quick copy/paste and nothing showed up. Double checked the code for the “PHP Snippet: Display Shipping Zones & Methods @ WooCommerce Single Product Page (WooCommerce Plugin)” version and there’s no “add_action” included.

        Once I added that your snippet worked just fine. It might be helpful to update the snippet to include that so that people don’t get confused as to why it’s not working. πŸ™‚

        1. Sorry about that. Fixed

  7. Hi Rodolfo

    long time subscriber first time commenting.

    is there any chance you could adapt this snippet so that it works with another marketplace plugin called WC vendors.

    I tried swapping yith_get_vendor for WCV_Vendors::is_vendor and WCV_Vendors::get_vendor_id but just gets a critical error. obviously, my cutting and pasting technique is being exposed here πŸ˜€

    thanks in advance

    1. Hey Mark, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  8. It shows for flat rate: € 0,00 instead of the right rate of € 8,00

    1. Not sure, works on my site. Can you try disable all plugins but Woo and test again?

  9. Hi Rodolfo!

    Love your blog, has helped me tremendously over the years.
    I work with geolocation for an even better conversion – customers in Italy have no need to see shipping rates/eta for Sweden for example. It will only confuse them.

    Tip: by adding a custom ETA field to the shipping methods you can specify the ETA per shipping method/zone. Any idea how we can present this custom field on the product page as well?

    1. Hey Wolf, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  10. Nice feature but it also shows “Free Shipping EURO 200” where it should rather say Free shipping above EURO 200 spend.

    1. Yep, you can totally add that (untested):

      $cost = $instance['cost'] ? $instance['cost'] : $instance['min_amount'];
      $above = $instance['min_amount'] ? 'above ' : '';
      echo $instance['title'] . ' ' . $above . wc_price( $cost ) . '<br>';
Questions? Feedback? Customization? Leave your comment now!

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *