PHPwoocommerceintermediate

WooCommerce Product Badges and Labels

Add custom badges and labels to WooCommerce products (Sale, New, Featured, Custom)

Faisal Yaqoob
#woocommerce#badges#labels#product-display#ui
Share this snippet:

Code

php
1// Display product badges on product listings and single product pages
2add_action('woocommerce_before_shop_loop_item_title', 'display_product_badges', 10);
3add_action('woocommerce_before_single_product_summary', 'display_product_badges', 10);
4
5function display_product_badges() {
6 global $product;
7
8 echo '<div class="product-badges">';
9
10 // Sale badge
11 if ($product->is_on_sale()) {
12 $percentage = '';
13
14 if ($product->get_type() === 'variable') {
15 $percentages = array();
16 $prices = $product->get_variation_prices();
17
18 foreach ($prices['price'] as $key => $price) {
19 if ($prices['regular_price'][$key] !== $price) {
20 $percentages[] = round((($prices['regular_price'][$key] - $price) / $prices['regular_price'][$key]) * 100);
21 }
22 }
23
24 if (!empty($percentages)) {
25 $percentage = max($percentages) . '%';
26 }
27 } elseif ($product->get_regular_price()) {
28 $percentage = round((($product->get_regular_price() - $product->get_sale_price()) / $product->get_regular_price()) * 100) . '%';
29 }
30
31 echo '<span class="badge badge-sale">';
32 echo $percentage ? '-' . $percentage : __('Sale', 'woocommerce');
33 echo '</span>';
34 }
35
36 // New badge (products created in last 30 days)
37 $post_date = get_the_time('U');
38 $thirty_days_ago = strtotime('-30 days');
39
40 if ($post_date > $thirty_days_ago) {
41 echo '<span class="badge badge-new">' . __('New', 'woocommerce') . '</span>';
42 }
43
44 // Featured product badge
45 if ($product->is_featured()) {
46 echo '<span class="badge badge-featured">' . __('Featured', 'woocommerce') . '</span>';
47 }
48
49 // Out of stock badge
50 if (!$product->is_in_stock()) {
51 echo '<span class="badge badge-out-of-stock">' . __('Out of Stock', 'woocommerce') . '</span>';
52 }
53
54 // Low stock badge
55 if ($product->is_in_stock() && $product->managing_stock()) {
56 $stock_quantity = $product->get_stock_quantity();
57 $low_stock_amount = get_option('woocommerce_notify_low_stock_amount', 2);
58
59 if ($stock_quantity <= $low_stock_amount && $stock_quantity > 0) {
60 echo '<span class="badge badge-low-stock">' . sprintf(__('Only %s left!', 'woocommerce'), $stock_quantity) . '</span>';
61 }
62 }
63
64 // Free shipping badge
65 if (has_term('free-shipping', 'product_tag', $product->get_id())) {
66 echo '<span class="badge badge-free-shipping">' . __('Free Shipping', 'woocommerce') . '</span>';
67 }
68
69 // Hot badge (best sellers or high demand)
70 if (has_term('hot', 'product_tag', $product->get_id())) {
71 echo '<span class="badge badge-hot">🔥 ' . __('Hot', 'woocommerce') . '</span>';
72 }
73
74 // Custom badge from product meta
75 $custom_badge = get_post_meta($product->get_id(), '_custom_badge', true);
76 if ($custom_badge) {
77 $badge_color = get_post_meta($product->get_id(), '_custom_badge_color', true);
78 $style = $badge_color ? 'style="background-color: ' . esc_attr($badge_color) . ';"' : '';
79 echo '<span class="badge badge-custom" ' . $style . '>' . esc_html($custom_badge) . '</span>';
80 }
81
82 echo '</div>';
83}

WooCommerce Product Badges and Labels

Add eye-catching badges to your WooCommerce products including Sale, New, Featured, Out of Stock, and custom badges.

// Display product badges on product listings and single product pages
add_action('woocommerce_before_shop_loop_item_title', 'display_product_badges', 10);
add_action('woocommerce_before_single_product_summary', 'display_product_badges', 10);

function display_product_badges() {
    global $product;

    echo '<div class="product-badges">';

    // Sale badge
    if ($product->is_on_sale()) {
        $percentage = '';

        if ($product->get_type() === 'variable') {
            $percentages = array();
            $prices = $product->get_variation_prices();

            foreach ($prices['price'] as $key => $price) {
                if ($prices['regular_price'][$key] !== $price) {
                    $percentages[] = round((($prices['regular_price'][$key] - $price) / $prices['regular_price'][$key]) * 100);
                }
            }

            if (!empty($percentages)) {
                $percentage = max($percentages) . '%';
            }
        } elseif ($product->get_regular_price()) {
            $percentage = round((($product->get_regular_price() - $product->get_sale_price()) / $product->get_regular_price()) * 100) . '%';
        }

        echo '<span class="badge badge-sale">';
        echo $percentage ? '-' . $percentage : __('Sale', 'woocommerce');
        echo '</span>';
    }

    // New badge (products created in last 30 days)
    $post_date = get_the_time('U');
    $thirty_days_ago = strtotime('-30 days');

    if ($post_date > $thirty_days_ago) {
        echo '<span class="badge badge-new">' . __('New', 'woocommerce') . '</span>';
    }

    // Featured product badge
    if ($product->is_featured()) {
        echo '<span class="badge badge-featured">' . __('Featured', 'woocommerce') . '</span>';
    }

    // Out of stock badge
    if (!$product->is_in_stock()) {
        echo '<span class="badge badge-out-of-stock">' . __('Out of Stock', 'woocommerce') . '</span>';
    }

    // Low stock badge
    if ($product->is_in_stock() && $product->managing_stock()) {
        $stock_quantity = $product->get_stock_quantity();
        $low_stock_amount = get_option('woocommerce_notify_low_stock_amount', 2);

        if ($stock_quantity <= $low_stock_amount && $stock_quantity > 0) {
            echo '<span class="badge badge-low-stock">' . sprintf(__('Only %s left!', 'woocommerce'), $stock_quantity) . '</span>';
        }
    }

    // Free shipping badge
    if (has_term('free-shipping', 'product_tag', $product->get_id())) {
        echo '<span class="badge badge-free-shipping">' . __('Free Shipping', 'woocommerce') . '</span>';
    }

    // Hot badge (best sellers or high demand)
    if (has_term('hot', 'product_tag', $product->get_id())) {
        echo '<span class="badge badge-hot">🔥 ' . __('Hot', 'woocommerce') . '</span>';
    }

    // Custom badge from product meta
    $custom_badge = get_post_meta($product->get_id(), '_custom_badge', true);
    if ($custom_badge) {
        $badge_color = get_post_meta($product->get_id(), '_custom_badge_color', true);
        $style = $badge_color ? 'style="background-color: ' . esc_attr($badge_color) . ';"' : '';
        echo '<span class="badge badge-custom" ' . $style . '>' . esc_html($custom_badge) . '</span>';
    }

    echo '</div>';
}

Add Custom Badge Field to Product Admin

// Add custom badge fields in product admin
add_action('woocommerce_product_options_general_product_data', 'add_custom_badge_field');
function add_custom_badge_field() {
    echo '<div class="options_group">';

    woocommerce_wp_text_input(array(
        'id'          => '_custom_badge',
        'label'       => __('Custom Badge Text', 'woocommerce'),
        'placeholder' => __('e.g., Limited Edition', 'woocommerce'),
        'desc_tip'    => true,
        'description' => __('Enter custom badge text for this product.', 'woocommerce'),
    ));

    woocommerce_wp_text_input(array(
        'id'          => '_custom_badge_color',
        'label'       => __('Badge Color', 'woocommerce'),
        'placeholder' => '#FF5733',
        'desc_tip'    => true,
        'description' => __('Enter hex color code for the badge.', 'woocommerce'),
        'type'        => 'color',
    ));

    echo '</div>';
}

// Save custom badge fields
add_action('woocommerce_process_product_meta', 'save_custom_badge_field');
function save_custom_badge_field($post_id) {
    $custom_badge = isset($_POST['_custom_badge']) ?
        sanitize_text_field($_POST['_custom_badge']) : '';
    update_post_meta($post_id, '_custom_badge', $custom_badge);

    $custom_badge_color = isset($_POST['_custom_badge_color']) ?
        sanitize_hex_color($_POST['_custom_badge_color']) : '';
    update_post_meta($post_id, '_custom_badge_color', $custom_badge_color);
}

Advanced Badge System with Conditions

// Advanced badge system with multiple conditions
function advanced_product_badges() {
    global $product;

    $badges = array();

    // Check for flash sale (ends within 24 hours)
    $sale_end_date = get_post_meta($product->get_id(), '_sale_price_dates_to', true);
    if ($sale_end_date) {
        $hours_left = ($sale_end_date - time()) / 3600;
        if ($hours_left > 0 && $hours_left <= 24) {
            $badges[] = array(
                'text'  => sprintf(__('Ends in %sh', 'woocommerce'), ceil($hours_left)),
                'class' => 'badge-flash-sale',
            );
        }
    }

    // Best seller badge (based on total sales)
    $total_sales = $product->get_total_sales();
    if ($total_sales > 100) {
        $badges[] = array(
            'text'  => __('Best Seller', 'woocommerce'),
            'class' => 'badge-best-seller',
        );
    }

    // Pre-order badge
    if (get_post_meta($product->get_id(), '_is_pre_order', true) === 'yes') {
        $badges[] = array(
            'text'  => __('Pre-Order', 'woocommerce'),
            'class' => 'badge-pre-order',
        );
    }

    // Eco-friendly badge
    if (has_term('eco-friendly', 'product_tag', $product->get_id())) {
        $badges[] = array(
            'text'  => '♻️ ' . __('Eco-Friendly', 'woocommerce'),
            'class' => 'badge-eco',
        );
    }

    // Display badges
    if (!empty($badges)) {
        echo '<div class="product-badges advanced">';
        foreach ($badges as $badge) {
            echo '<span class="badge ' . esc_attr($badge['class']) . '">' .
                 esc_html($badge['text']) . '</span>';
        }
        echo '</div>';
    }
}

Category-Specific Badges

// Display badges based on product category
function category_based_badges() {
    global $product;

    $categories = wp_get_post_terms($product->get_id(), 'product_cat', array('fields' => 'slugs'));

    echo '<div class="product-badges category-badges">';

    if (in_array('organic', $categories)) {
        echo '<span class="badge badge-organic">🌿 ' . __('Organic', 'woocommerce') . '</span>';
    }

    if (in_array('handmade', $categories)) {
        echo '<span class="badge badge-handmade">✋ ' . __('Handmade', 'woocommerce') . '</span>';
    }

    if (in_array('exclusive', $categories)) {
        echo '<span class="badge badge-exclusive">⭐ ' . __('Exclusive', 'woocommerce') . '</span>';
    }

    echo '</div>';
}

CSS Styling for Badges

/* Product badges container */
.product-badges {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 10;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

/* Base badge styles */
.badge {
    display: inline-block;
    padding: 5px 12px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    border-radius: 3px;
    color: white;
    line-height: 1.4;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* Sale badge */
.badge-sale {
    background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
}

/* New badge */
.badge-new {
    background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}

/* Featured badge */
.badge-featured {
    background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
    color: #333;
}

/* Out of stock badge */
.badge-out-of-stock {
    background: #999;
}

/* Low stock badge */
.badge-low-stock {
    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}

/* Free shipping badge */
.badge-free-shipping {
    background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
}

/* Hot badge */
.badge-hot {
    background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
    animation: pulse 2s infinite;
}

/* Best seller badge */
.badge-best-seller {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* Flash sale badge */
.badge-flash-sale {
    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    animation: flash 1.5s infinite;
}

/* Eco-friendly badge */
.badge-eco {
    background: linear-gradient(135deg, #56ab2f 0%, #a8e063 100%);
}

/* Pre-order badge */
.badge-pre-order {
    background: linear-gradient(135deg, #f5af19 0%, #f12711 100%);
}

/* Custom badge */
.badge-custom {
    background: #333;
}

/* Animations */
@keyframes pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
}

@keyframes flash {
    0%, 50%, 100% {
        opacity: 1;
    }
    25%, 75% {
        opacity: 0.7;
    }
}

/* Single product page adjustments */
.single-product .product-badges {
    top: 20px;
    left: 20px;
}

/* Responsive */
@media (max-width: 768px) {
    .product-badges {
        top: 5px;
        left: 5px;
    }

    .badge {
        font-size: 10px;
        padding: 4px 8px;
    }
}

Remove Default WooCommerce Sale Badge

// Remove default WooCommerce sale flash
remove_action('woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10);
remove_action('woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10);

Features

  • Multiple Badge Types: Sale, New, Featured, Out of Stock, Low Stock, and more
  • Dynamic Sale Percentage: Calculates and displays discount percentage
  • Custom Badges: Add custom text and colors via product admin
  • Category-Based: Automatic badges based on product categories
  • Condition-Based: Badges based on stock, sales, dates, etc.
  • Time-Sensitive: Flash sale countdown badges
  • Fully Styled: Beautiful gradient CSS with animations
  • Responsive: Mobile-friendly badge display
  • Emoji Support: Use emojis for visual appeal
  • Extensible: Easy to add new badge types

Dependencies

  • WooCommerce

Related Snippets