Product badges disappear in block themes like Twenty Twenty-Five because WooCommerce Blocks bypass PHP hooks. Learn why this happens, which plugins are affected, and 3 ways to fix it.
March 5, 2026 · 5 min read
You just switched your WooCommerce store to a modern block theme — Twenty Twenty-Five, Flavor, Flavor Dark, or Flavor flavor. Everything looks great, except your product badges have disappeared.
No “Sale” labels. No “New” tags. Nothing.
You check the plugin settings — badges are still active. You switch back to your old theme — badges reappear. What’s going on?
This is one of the most common compatibility issues with WooCommerce block themes, and it affects most badge plugins on the market. Here’s why it happens and how to fix it.
Traditional WooCommerce themes (Storefront, Astra, OceanWP) render products using PHP action hooks — specifically:
woocommerce_before_shop_loop_item_titlewoocommerce_product_get_imagewoocommerce_before_single_product_summaryBadge plugins inject their HTML into these hooks. When WooCommerce fires the hook, the badge appears.
Block themes work differently. Products are rendered by WooCommerce Blocks — React-based components that bypass traditional PHP hooks entirely. The hooks simply never fire, so badges never appear.
This isn’t a bug in any specific plugin — it’s an architectural difference between classic and block-based rendering.
Most popular badge plugins were built for classic themes and have limited or no support for block themes:
YITH WooCommerce Badge Management — Multiple reports of badges not appearing in block-based layouts. In one support thread, 11 users reported the same issue, and it remains unresolved. YITH support suggested custom PHP hooks as a workaround, but it doesn’t solve the core problem.
Sold Out Badge for WooCommerce — The plugin author explicitly confirmed that the plugin “isn’t compatible with WooCommerce Gutenberg blocks.”
BeRocket Advanced Product Labels — Users migrating to block-based themes like Kadence reported that labels stopped appearing.
The pattern is clear: if a badge plugin relies only on classic WooCommerce hooks, it will break in block themes.
If you just need to restyle the default WooCommerce “Sale!” badge, CSS works in both classic and block themes:
/* Override default sale badge */
.wc-block-components-product-sale-badge,
.onsale {
background: linear-gradient(135deg, #e53935, #d32f2f) !important;
color: #fff !important;
font-size: 12px !important;
font-weight: 700 !important;
padding: 4px 10px !important;
border-radius: 4px !important;
text-transform: uppercase !important;
letter-spacing: 0.5px !important;
}
Pros: Zero dependencies, works everywhere. Cons: Only works for the default “Sale” badge. You can’t add “New”, “Low Stock”, or custom badges with CSS alone — those require product-level logic.
render_block FilterThe correct way to inject badges into block-rendered products is to filter the block output HTML rather than relying on classic hooks:
add_filter('render_block', function($block_content, $block) {
if ($block['blockName'] !== 'woocommerce/product-image') {
return $block_content;
}
// Get the product context
$product_id = $block['attrs']['productId'] ?? null;
if (!$product_id) {
return $block_content;
}
$product = wc_get_product($product_id);
if (!$product) {
return $block_content;
}
$badge_html = '';
// "Sale" badge
if ($product->is_on_sale()) {
$badge_html .= '<span class="custom-badge sale-badge">SALE</span>';
}
// "New" badge (published within last 30 days)
$created = $product->get_date_created();
if ($created) {
$days = (time() - $created->getTimestamp()) / DAY_IN_SECONDS;
if ($days <= 30) {
$badge_html .= '<span class="custom-badge new-badge">NEW</span>';
}
}
if (!$badge_html) {
return $block_content;
}
// Inject badge into the block HTML
return '<div style="position:relative;">' . $badge_html . $block_content . '</div>';
}, 10, 2);
Add the CSS:
.custom-badge {
position: absolute;
top: 8px;
left: 8px;
z-index: 10;
padding: 4px 10px;
font-size: 12px;
font-weight: 700;
color: #fff;
border-radius: 4px;
line-height: 1.4;
}
.sale-badge {
background: linear-gradient(135deg, #e53935, #d32f2f);
}
.new-badge {
background: linear-gradient(135deg, #4ade80, #22c55e);
top: 8px;
left: auto;
right: 8px;
}
Pros: Works with both block and classic themes, uses the correct WordPress API. Cons: Requires code maintenance, no admin UI, need to handle edge cases (variable products, caching, multiple badges).
Some plugins already use the render_block approach internally:
BadgePro — Built specifically for modern WooCommerce. Uses render_block filter combined with DOM parsing to inject badges correctly in both block and classic themes. Works out of the box with Twenty Twenty-Three, Twenty Twenty-Four, and Twenty Twenty-Five.
WPC Badge Management — Claims general theme compatibility but doesn’t explicitly document block theme support.
When evaluating a badge plugin, check for these indicators of block theme support:
For developers who want to understand the full picture:
PHP Template → woocommerce_before_shop_loop_item_title hook → Badge Plugin injects HTML → Browser renders
The plugin hooks into the template lifecycle. Direct, simple, reliable.
Block Editor → React Component → Server-Side Render → HTML String → Browser renders
No PHP hooks fire during block rendering. The only interception point is the render_block filter, which receives the final HTML string and lets you modify it before output.
render_block Looks LikeWordPress calls render_block for every block on the page. A badge plugin needs to:
woocommerce/product-image blocksThis is more complex than classic hooks but it’s the only reliable approach for block themes.
| Method | Classic Themes | Block Themes | Effort |
|---|---|---|---|
| CSS override | ✅ | ✅ | Low (sale badge only) |
| Classic PHP hooks | ✅ | ❌ | Medium |
render_block filter |
✅ | ✅ | High |
| Plugin with block support | ✅ | ✅ | Low |
If your badges stopped working after switching to a block theme, you’re not alone — it’s an architectural limitation that affects most plugins. The render_block filter is the correct solution, whether you implement it yourself or choose a plugin that does it for you.
WordPress is moving toward block themes as the default. If you’re choosing a badge plugin today, make sure it works with the theme architecture you’ll be using tomorrow.
Published by CartEngine. We build lightweight WooCommerce tools that actually work.
More Articles