---
title: WooCommerce Product Labels Plugin — Badge Configuration
type: article
created: '2026-04-05'
updated: '2026-04-05'
source_docs:
- raw/2026-03-09-check-in-markkarly-128339591.md
tags:
- woocommerce
- wordpress
- badges
- product-labels
- z-index
- wp-rocket
- caching
- debugging
layer: 2
client_source: null
industry_context: null
transferable: true
---

# WooCommerce Product Labels Plugin — Badge Configuration

## Overview

The **Product Labels for WooCommerce** plugin (EcoWebs) allows custom badges to be applied to product thumbnails in WooCommerce shop pages. Configuration is non-obvious in several areas, and client self-editing frequently breaks badge setups. This article documents key configuration patterns, known failure modes, and workarounds discovered during the [[clients/flynn/index|Flynn]] project.

---

## Core Concepts

### Badge Types

The plugin supports two badge tiers:

- **Standard badges** — simple CSS-based labels (e.g., "Sale")
- **Advanced badges** — custom-styled badges with shape, color, and position control; these are what enable branded labels like "Open Box"

### Product Lists

Badges are not applied directly to products. Instead, you create a **Product List** that defines which products receive a badge, then assign a badge to that list.

Product lists can be scoped by:
- **Category** — any product in a given WooCommerce category
- **Tag**
- **Manual product selection** — type product names to add individually

> **Gotcha:** The category search field in the Product List UI does not auto-populate. You must start typing the category name before results appear.

### Sale Badge Behavior

The "Sale" badge is triggered automatically by WooCommerce's on-sale flag (i.e., when a product has a reduced price set). It does **not** require a Product List. This means it will appear on any discounted product regardless of other badge configuration.

---

## Badge Stacking and Z-Index

### The Problem

When two badges are assigned to the same position (e.g., both top-left), they overlap. The plugin's UI exposes a **Z-Index** field per badge, but this does not reliably control stacking order when the two badges are of different types (e.g., one standard, one advanced).

**Root cause:** Each badge type renders in its own absolutely-positioned container. CSS `z-index` only controls stacking within the same stacking context. Badges in separate containers are unaffected by each other's `z-index` values.

### Confirmed Workaround

Give each badge a **distinct position**:

- Place the "Sale" badge at **top-left**
- Place the "Open Box" badge at **top-right**

This avoids the overlap entirely and communicates both statuses clearly. The client (Flynn) confirmed this was acceptable.

### Attempted Z-Index Fix (Partially Works for Same-Type Badges)

If both badges are the same type, z-index *can* work:

1. Open the badge settings for the badge you want on top
2. Set its **Z-Index** to a higher value (e.g., `10`)
3. Set the competing badge's Z-Index to a lower value (e.g., `5`)

Note: the Sale badge had a default Z-Index of `99` — this must be lowered explicitly if you want another badge to appear above it.

---

## Category-Based Badge Application

To apply a badge to all products in a WooCommerce category (e.g., "Open Box"):

1. Go to **Badges → Product Lists → Add New List**
2. Name the list (e.g., "Open Box")
3. Set **Taxonomy** to `Category`
4. In the **Select Type** field, start typing the category name — results will appear
5. Select the category and save
6. Assign this Product List to the desired badge in the badge's **Product Selection** settings

---

## Lazy Loading / Caching Conflict

### Symptom

Badges do not appear when a user first loads a filtered shop page (e.g., clicking the "Open Box" category filter). They only appear after a manual browser refresh.

### Root Cause

Badges are injected into the DOM via JavaScript **after** the initial page load. When [[knowledge/wordpress/wp-rocket|WP Rocket]] serves a cached page, the badge injection script may run late or not at all on the first render. This is compounded by WooCommerce's AJAX-based product filtering, which re-renders the product grid without triggering a full page load.

### Diagnosis Method

Fetch the raw page HTML (e.g., via `curl` or browser dev tools → View Source). If badge markup is absent from the initial HTML, the badges are being injected client-side and are subject to this race condition.

### Resolution (In Progress)

A custom **Must Use (MU) plugin** is being developed to address this. The approach uses a `MutationObserver` to detect when the product grid is re-rendered by AJAX filtering and re-trigger badge injection at that point.

> **Status as of 2026-04-05:** MU plugin in development. See [[clients/flynn/index|Flynn]] action items.

### Interim Mitigation

- Clear WP Rocket cache after any badge configuration change
- Clear both the WP Rocket cache and the CDN/browser cache layers when testing

---

## Plugin Settings Reference

Key settings under **Badges → Settings → General**:

| Setting | Purpose |
|---|---|
| **Disable Default Badge** | Suppresses WooCommerce's built-in "Sale" / "Out of Stock" labels. Enable this when using custom badges to avoid duplication. |
| **Use WooCommerce Shop Hook** | Default rendering method; appends badges to product thumbnails |
| **Enable Product Loop Hook** | Fallback if badges aren't displaying; some themes override the default hook. **Warning:** enabling this when badges are already showing can cause duplicates. |
| **Enable Product Title Hook** | Secondary fallback; generally not needed |

---

## Client Self-Editing Risk

A recurring issue on the Flynn account is the client modifying badge settings directly in WordPress. Because the plugin's configuration is stateful (badges, product lists, and hook settings interact), a single inadvertent change can break badge display entirely and leave no obvious audit trail.

**Recommended approach:** Communicate clearly that badge configuration changes should be submitted as requests rather than made directly. Estimated time to diagnose a client-introduced regression: 1–2 hours.

---

## Related

- [[clients/flynn/index|Flynn Client]]
- [[knowledge/wordpress/wp-rocket|WP Rocket Caching]]
- [[knowledge/woocommerce/product-categories|WooCommerce Product Categories]]