How to Create Custom Product Badges for Woocommerce?

By default Woocommerce has only “Sale” and “Out of stock” badges but what if you need to create custom product badges? For example, automatic product badge for a featured product or “New” badge for products that are newer than 30 days? Or even custom text badges with “Free shipping” or “Top product” text?

Well, be that as it may, in this post I’m going to show you how to display custom product badges on WooCommerce.

Video: How to Create Custom Product Badges for Woocommerce?

If you’re not familiar with the coding or using code snippets, then I would suggest you to take a look at the video here below. In it I will show you how to create custom product badges for Woocommerce in a way that is described also in this post.

Code snippets plugin or functions.php file?

All the snippets shown here below should be added either to your child theme’s functions.php file or better yet – use Code Snippets plugin for it.

WpCodeBox is my favorite code snippets manager for WordPress. This is a premium plugin and if you’re interested, then grab WPCodeBox with a nice 20% discount here (SAVE 20% Coupon WPSH20).

All CSS code goes to the Appearance >> Customizer >> Additional CSS box.

Pay attention though, that you most likely need to tweak this CSS in a way that it looks good with your theme.

Display Woocommerce Discount as a percentage on the Sale Badge?

So, your Woocommerce sale product has a default badge with text “Sale”. With the snippet here below, you can display the Woocommerce discount as a percentage on a sale badge. It also works with variable products.

PS! If needed then change or remove “up to -” text in the line 51 of this code.

<span role="button" tabindex="0" data-code="// Display the Woocommerce Discount Percentage on the Sale Badge for variable products and single products
add_filter( 'woocommerce_sale_flash', 'display_percentage_on_sale_badge', 20, 3 );
function display_percentage_on_sale_badge( $html, $post, $product ) {

if( $product->is_type('variable')){
$percentages = array();

// This will get all the variation prices and loop throughout them
$prices = $product->get_variation_prices();

foreach( $prices['price'] as $key => $price ){
// Only on sale variations
if( $prices['regular_price'][$key] !== $price ){
// Calculate and set in the array the percentage for each variation on sale
$percentages[] = round( 100 – ( floatval($prices['sale_price'][$key]) / floatval($prices['regular_price'][$key]) * 100 ) );
}
}
// Displays maximum discount value
$percentage = max($percentages) . '%';

} elseif( $product->is_type('grouped') ){
$percentages = array();

// This will get all the variation prices and loop throughout them
$children_ids = $product->get_children();

foreach( $children_ids as $child_id ){
$child_product = wc_get_product($child_id);

$regular_price = (float) $child_product->get_regular_price();
$sale_price = (float) $child_product->get_sale_price();

if ( $sale_price != 0 || ! empty($sale_price) ) {
// Calculate and set in the array the percentage for each child on sale
$percentages[] = round(100 – ($sale_price / $regular_price * 100));
}
}
// Displays maximum discount value
$percentage = max($percentages) . '%';

} else {
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();

if ( $sale_price != 0 || ! empty($sale_price) ) {
$percentage = round(100 – ($sale_price / $regular_price * 100)) . '%';
} else {
return $html;
}
}
return '<span class="onsale perc">' . esc_html__( 'up to -', 'woocommerce' ) . ' '. $percentage . '

// Display the Woocommerce Discount Percentage on the Sale Badge for variable products and single products
add_filter( 'woocommerce_sale_flash', 'display_percentage_on_sale_badge', 20, 3 );
function display_percentage_on_sale_badge( $html, $post, $product ) {

  if( $product->is_type('variable')){
      $percentages = array();

      // This will get all the variation prices and loop throughout them
      $prices = $product->get_variation_prices();

      foreach( $prices['price'] as $key => $price ){
          // Only on sale variations
          if( $prices['regular_price'][$key] !== $price ){
              // Calculate and set in the array the percentage for each variation on sale
              $percentages[] = round( 100 - ( floatval($prices['sale_price'][$key]) / floatval($prices['regular_price'][$key]) * 100 ) );
          }
      }
      // Displays maximum discount value
      $percentage = max($percentages) . '%';

  } elseif( $product->is_type('grouped') ){
      $percentages = array();

       // This will get all the variation prices and loop throughout them
      $children_ids = $product->get_children();

      foreach( $children_ids as $child_id ){
          $child_product = wc_get_product($child_id);

          $regular_price = (float) $child_product->get_regular_price();
          $sale_price    = (float) $child_product->get_sale_price();

          if ( $sale_price != 0 || ! empty($sale_price) ) {
              // Calculate and set in the array the percentage for each child on sale
              $percentages[] = round(100 - ($sale_price / $regular_price * 100));
          }
      }
     // Displays maximum discount value
      $percentage = max($percentages) . '%';

  } else {
      $regular_price = (float) $product->get_regular_price();
      $sale_price    = (float) $product->get_sale_price();

      if ( $sale_price != 0 || ! empty($sale_price) ) {
          $percentage    = round(100 - ($sale_price / $regular_price * 100)) . '%';
      } else {
          return $html;
      }
  }
  return '<span class="onsale perc">' . esc_html__( 'up to -', 'woocommerce' ) . ' '. $percentage . '</span>'; // If needed then change or remove "up to -" text
}

Now, if you would like to customize the styling of this sale badge, then use this piece of CSS and the end result looks like the one in the screenshot.

How to display custom product badges on WooCommerce?

Custom CSS for the sale badge (optional)

.onsale.perc:after {
	border: 5px solid #ffcc00;
border-color: transparent transparent #ffcc00 #ffcc00;
	border-width: 9px 6px;
	position: absolute;
	right: -10px;
	bottom: 0;
	content: '';
}
.onsale.perc:before {
border: 5px solid #ffcc00;
    border-color: #ffcc00 transparent transparent #ffcc00;
    border-width: 9px 6px;
    position: absolute;
    right: -10px;
    top: 0;
    content: '';
}
.onsale.perc {
	top: 16px;
	left: 0px;
}

How to display “New” badge for recent products?

With the help of this piece of code here below, you can display “new” badge for products that are newer than 30 days. If you need to change number of days then change number in line 6 and line 17 ( $newness_days = 30;)

Pay attention that this badge is shown both on archive and single product pages. If you don’t need to display it either here or there, then just remove the first or second part of the code.

<span role="button" tabindex="0" data-code="// New badge for recent products (archive)
add_action( 'woocommerce_before_shop_loop_item_title', 'new_badge', 3 );

function new_badge() {
global $product;
$newness_days = 30; // Number of days the badge is shown
$created = strtotime( $product->get_date_created() );
if ( ( time() – ( 60 * 60 * 24 * $newness_days ) ) < $created ) {
echo '<span class="ct-woo-card-extra new-badge">' . esc_html__( 'NEW', 'woocommerce' ) . '</span>';
}
}

// New badge for recent products on single product page
add_action( 'woocommerce_single_product_summary', 'new_badge_single_product', 1 );
function new_badge_single_product() {
global $product;
$newness_days = 30; // Number of days the badge is shown
$created = strtotime( $product->get_date_created() );
if ( ( time() – ( 60 * 60 * 24 * $newness_days ) ) < $created ) {
echo '<span class="itsnew">' . esc_html__( 'NEW', 'woocommerce' ) . '

// New badge for recent products (archive)
add_action( 'woocommerce_before_shop_loop_item_title', 'new_badge', 3 );
          
function new_badge() {
   global $product;
   $newness_days = 30; // Number of days the badge is shown
   $created = strtotime( $product->get_date_created() );
   if ( ( time() - ( 60 * 60 * 24 * $newness_days ) ) < $created ) {
      echo '<span class="ct-woo-card-extra new-badge">' . esc_html__( 'NEW', 'woocommerce' ) . '</span>';
   }
}

// New badge for recent products on single product page
add_action( 'woocommerce_single_product_summary', 'new_badge_single_product', 1 );  
function new_badge_single_product() {
   global $product;
   $newness_days = 30; // Number of days the badge is shown
   $created = strtotime( $product->get_date_created() );
   if ( ( time() - ( 60 * 60 * 24 * $newness_days ) ) < $created ) {
      echo '<span class="itsnew">' . esc_html__( 'NEW', 'woocommerce' ) . '</span>';
   }
}

Custom CSS for the new badge (see the comments for archive and single product page in code)

/* New badge in archive page */
.ct-woo-card-extra.new-badge{
	position: absolute;
    background: #E54C60;
	color: #fff;
	font-weight: 700;
	text-transform: uppercase;
	border-radius: 50px;
	font-size: 10px;
	padding: 5px;
	right: 15px;
	z-index: 2;
	display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
	top: 110px;
}
/* New badge in single product page page */
.itsnew {
   background: #f37b21;
   padding: 5px 10px;
   font-size: 12px;
   font-weight: 600;
   color: #fff;
   margin-top: 15px;
   float: right;
   top: 15px;
}

How to display featured product badge in Woocommerce?

Next let’s add a featured product badge in Woocommerce. This means that if the product is set as “featured” then the badge is shown automatically both on category and single product page. If you would like to display it only on one of these places then remove other par of the code.

If you would like to change the label “featured” for anything else, then change it on lines 17 and 38.

This should be the end result with discount percentage badge, “new” badge and featured product badge.

How to display featured product badge in Woocommerce?

// Display featured product badge in Woocommerce archive page
add_action( 'woocommerce_before_shop_loop_item_title', 'featured_badge_on_archive_pages', 10 );
// add_action( 'blocksy:woocommerce:product-card:title:before', 'featured_badge_on_archive_pages', 1 );
function featured_badge_on_archive_pages() {
    global $product;
    
    // Is a WC product
    if ( is_a( $product, 'WC_Product' ) ) {
        // Get productID
        $product_id = $product->get_id();
        
        // Returns an array containing the IDs of the featured products.
        $featured_product_ids = wc_get_featured_product_ids();
        
        // Checks if a value exists in an array
        if ( in_array( $product_id, $featured_product_ids ) ) {
            echo '<span class="featured-badge">Featured</span>';
        } 
    }
}

// Display featured product badge in Woocommerce single product page

add_action( 'woocommerce_single_product_summary', 'featured_badge_on_product_pages', 1 );
function featured_badge_on_product_pages() {
    global $product;
    
    // Is a WC product
    if ( is_a( $product, 'WC_Product' ) ) {
        // Get productID
        $product_id = $product->get_id();
        
        // Returns an array containing the IDs of the featured products.
        $featured_product_ids = wc_get_featured_product_ids();
        
        // Checks if a value exists in an array
        if ( in_array( $product_id, $featured_product_ids ) ) {
            echo '<span class="featured1">Featured</span>';
        } 
    }
}

Custom CSS for the featured product badge.

/* Woocommerce featured product badge on archive pages */
.featured-badge  {
	top: 20px;
	left: 0px;
	width: 100%;
	background: #1e1e1e99;
	color: #fff;
 display: flex;
  justify-content: center;
	position: absolute;
	z-index: 1;
		font-size: 13px;
	text-transform: uppercase;
	font-weight: 600;
}
/* Woocommerce featured product badge in single product page */
.featured1 {
	background: #fff000;
	color: #000;
	font-weight: 600;
	text-transform: uppercase;
	padding: 5px 10px;
  font-size: 12px;
	font-weight: 600;
margin-top: 15px;
	float: right;
}

How to display custom product badges with checking a checkbox?

Next, let’s add a checkbox at your single product edit page. If you check this then the text “Free shipping” is shown on the single product page below the title. See these screenshots here below, and you’ll see how it will also display it for the badge we’re going to create in the next chapter.

How to display custom product badges on WooCommerce?
How to display custom product badges on WooCommerce?

If you would like to change the text shown in the badge, then just modify it in line 34. Also, change the text in lines 7 and 9 accordingly.

Now, let’s display custom product badges with checking a checkbox.

<span role="button" tabindex="0" data-code="// Step 1: Add checkbox

add_action( 'woocommerce_product_options_general_product_data', 'checkbox_badge' );

function checkbox_badge() {
woocommerce_wp_checkbox( array(
'id' => 'checkbox_badge',
'class' => '',
'label' => 'Display free shipping badge'
)
);
}

// Step 2: Save checkbox selection

add_action( 'save_post', 'save_checkbox_badge_selection' );

function save_checkbox_badge_selection( $product_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( isset( $_POST['checkbox_badge'] ) ) {
update_post_meta( $product_id, 'checkbox_badge', $_POST['checkbox_badge'] );
} else delete_post_meta( $product_id, 'checkbox_badge' );
}

// Step 3: Display custom badge at single product page

add_action( 'woocommerce_single_product_summary', 'display_checkbox_badge', 7 );

function display_checkbox_badge() {
global $product;
if ( get_post_meta( $product->get_id(), 'checkbox_badge', true ) ) {
echo '
<div class="custom-badge-1">Free shipping

// Step 1: Add checkbox 

add_action( 'woocommerce_product_options_general_product_data', 'checkbox_badge' );        
  
function checkbox_badge() {           
woocommerce_wp_checkbox( array( 
'id' => 'checkbox_badge', 
'class' => '', 
'label' => 'Display free shipping badge'
) 
);      
}

// Step 2: Save checkbox selection
  
add_action( 'save_post', 'save_checkbox_badge_selection' );
  
function save_checkbox_badge_selection( $product_id ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;
    if ( isset( $_POST['checkbox_badge'] ) ) {
            update_post_meta( $product_id, 'checkbox_badge', $_POST['checkbox_badge'] );
    } else delete_post_meta( $product_id, 'checkbox_badge' );
}

// Step 3: Display custom badge at single product page
  
add_action( 'woocommerce_single_product_summary', 'display_checkbox_badge', 7 );
  
function display_checkbox_badge() {
    global $product;     
    if ( get_post_meta( $product->get_id(), 'checkbox_badge', true ) ) {
        echo '
<div class="custom-badge-1">Free shipping</div>'; // Change this text if needed
    }
}

Custom CSS for the product badge.

/* Display custom product badges with checking a checkbox */
.custom-badge-1 {
  font-size: 13px;
	color: #fff;
	font-weight: 600;
	background: #E54C60;
	border: 2px solid #E54C60;
	text-align: center;
	padding: 7px;
	display: inline;
}
.entry-summary .price {
	margin-top: 1em;
}

How to display Woocommerce product badge with custom text?

Last badge we’re going to create today is the one that allows us to display Woocommerce product badge with custom text. It will add a text box inside your product edit page (see the screenshot above) and will display the text you entered on single product page.

<span role="button" tabindex="0" data-code="// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_fields' );

// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_fields_save' );

function woo_add_custom_fields() {

global $woocommerce, $post;

echo '<div class="options_group">';

// Display Woocommerce product badge box in product edit page
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'Badge text', 'woocommerce' ),
'placeholder' => 'Enter your badge text here',
'desc_tip' => 'true',
'description' => __( 'Enter your badge text here', 'woocommerce' )
)
);
echo '</div>';
}
function woo_add_custom_fields_save( $post_id ){
// Text Field
$woocommerce_text_field = $_POST['_text_field'];
if(!empty( $woocommerce_text_field )) {
update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) );
} else {
update_post_meta( $post_id, '_text_field', "" );
}
}

// Display Woocommerce product badge with custom text in single product page
add_action('woocommerce_single_product_summary', 'display_custom_field_value', 7 );
function display_custom_field_value(){
$value = get_post_meta( get_the_ID(), '_text_field', true);
if(strlen($value) != null && strlen($value) > 0) {
echo '<div class="custom-badge">'.get_post_meta( get_the_ID(), '_text_field', true ).'

// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_fields' );

// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_fields_save' );

function woo_add_custom_fields() {

  global $woocommerce, $post;
  
  echo '<div class="options_group">';
  
 // Display Woocommerce product badge box in product edit page
woocommerce_wp_text_input( 
	array( 
		'id'          => '_text_field', 
		'label'       => __( 'Badge text', 'woocommerce' ), 
		'placeholder' => 'Enter your badge text here',
		'desc_tip'    => 'true',
		'description' => __( 'Enter your badge text here', 'woocommerce' ) 
	)
); 
  echo '</div>';	
}
function woo_add_custom_fields_save( $post_id ){
	// Text Field
	$woocommerce_text_field = $_POST['_text_field'];
  if(!empty( $woocommerce_text_field )) {
	update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) );
  } else {
	update_post_meta( $post_id, '_text_field', "" );
  }
}

// Display Woocommerce product badge with custom text in single product page
add_action('woocommerce_single_product_summary', 'display_custom_field_value', 7 );
function display_custom_field_value(){
  $value = get_post_meta( get_the_ID(), '_text_field', true);
  if(strlen($value) != null && strlen($value) > 0) {
	echo '<div class="custom-badge">'.get_post_meta( get_the_ID(), '_text_field', true ).'</div>';
  }
}

Custom CSS for the badge

/* Display Woocommerce product badge with custom text in single product page */
.custom-badge {
  font-size: 13px;
	color: #1e1e1e;
	font-weight: 600;
	border: 2px dashed #ddd;
	background: #f9f9f9;
	padding: 7px;
	display: inline;
	margin-left: 10px;
}
.entry-summary .price {
	margin-top: 1em;
}

So, there you go. Now you know how to create custom product badges and display then in a way you like.

Useful Woocommerce tips

  • How to filter WooCommerce admin products by on sale?
  • Woocommerce – Disable Payment Methods Based on User Roles
  • How to sell tickets with Woocommerce?
  • 12 useful Woocommerce snippets & hacks
  • How to display Woocommerce store address for Local pickup shipping method?
  • How to Hide Woocommerce shipping methods for specific shipping classes?
  • How to rename, remove, reorder and add Woocommerce My Account tabs?

Leave a Comment

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

Scroll to Top