Back to Woocommerce

On-Sale Badge block

docs/block-development/extensible-blocks/product-sale-badge-block/README.md

10.8.0-dev3.7 KB
Original Source

On-Sale Badge block

The On-Sale Badge block displays a "Sale" badge on products that are on sale.

Note: This block uses the slug woocommerce/product-sale-badge.

woocommerce_sale_badge_text

Description

The woocommerce_sale_badge_text filter allows customization of the sale badge text based on product context.

Parameters

  • $sale_text string (default: 'Sale') - The sale badge text.
  • $product WC_Product - The product object.

Returns

  • string - The filtered sale badge text.

Code examples

Basic example

php
add_filter( 'woocommerce_sale_badge_text', 'custom_sale_badge_text', 10, 2 );

function custom_sale_badge_text( $sale_text, $product ) {
	return __( 'On Sale', 'your-textdomain' );
}

Product-specific customization

php
add_filter( 'woocommerce_sale_badge_text', 'custom_sale_badge_by_product_type', 10, 2 );

function custom_sale_badge_by_product_type( $sale_text, $product ) {
	if ( $product->is_type( 'variable' ) ) {
		return __( 'Save Now', 'your-textdomain' );
	}

	if ( $product->is_type( 'simple' ) ) {
		return __( 'Limited Offer', 'your-textdomain' );
	}

	return $sale_text;
}

Discount percentage

php
add_filter( 'woocommerce_sale_badge_text', 'show_discount_percentage_badge', 10, 2 );

function show_discount_percentage_badge( $sale_text, $product ) {
	if ( $product->is_type( 'simple' ) || $product->is_type( 'external' ) ) {
		$regular_price = (float) $product->get_regular_price();
		$sale_price    = (float) $product->get_sale_price();

		if ( $regular_price > 0 ) {
			$percentage = round( ( ( $regular_price - $sale_price ) / $regular_price ) * 100 );
			return sprintf( __( '-%s%%', 'your-textdomain' ), $percentage );
		}
	}

	return $sale_text;
}

Difference from woocommerce_sale_flash

Aspectwoocommerce_sale_badge_textwoocommerce_sale_flash
ContextOn-Sale Badge blockClassic templates (loop/sale-flash.php, single-product/sale-flash.php)
OutputPlain textHTML markup
Parameters$sale_text, $product$html, $post, $product
Default'Sale''<span class="onsale">Sale!</span>'
SinceWooCommerce 10.0.0WooCommerce 2.x

Output handling

The block filter expects plain text only. HTML tags will be escaped and displayed as text.

php
// Correct - plain text
add_filter( 'woocommerce_sale_badge_text', function( $text, $product ) {
	return 'Hot Deal';
}, 10, 2 );

// Incorrect - HTML will be escaped
add_filter( 'woocommerce_sale_badge_text', function( $text, $product ) {
	return '<strong>Hot Deal</strong>'; // Displays as "&lt;strong&gt;Hot Deal&lt;/strong&gt;"
}, 10, 2 );

The classic filter expects HTML markup:

php
add_filter( 'woocommerce_sale_flash', function( $html, $post, $product ) {
	return '<span class="onsale">Hot Deal</span>';
}, 10, 3 );

Supporting both

To support both block and classic themes, implement both filters:

php
// Block filter
add_filter( 'woocommerce_sale_badge_text', 'my_custom_sale_badge', 10, 2 );

function my_custom_sale_badge( $sale_text, $product ) {
	return __( 'Special Offer', 'your-textdomain' );
}

// Classic filter
add_filter( 'woocommerce_sale_flash', 'my_classic_sale_flash', 10, 3 );

function my_classic_sale_flash( $html, $post, $product ) {
	return '<span class="onsale">' . __( 'Special Offer', 'your-textdomain' ) . '</span>';
}

Notes

  • The sale badge only renders when $product->is_on_sale() returns true.
  • Filter output is escaped with esc_html() by the block.
  • For Cart and Checkout blocks, use the saleBadgePriceFormat filter instead.