PLP Badges
Badges displayed on Product Listing Pages (PLPs) are managed through the static-assets repository and rendered via SearchSpring's search results.
Implementationโ
Badge Generationโ
Badges are generated in the sharedPlugin function within src/shared/shared/plugins/shared.js. The plugin runs during the afterStore hook and processes each search result to determine which badge to display.
// Badge is attached to each result
result.custom.badge = {
id: 'new',
label: 'New Arrival',
class: 'icon-tag new-arrival-tag',
bgColor: undefined,
color: undefined
};
Badge Renderingโ
Badges are rendered in src/shared/result/Result.jsx:
{result.custom.badge && (
<div className={`grid gap-1 ${result.custom.badge.class}`}>
<span
style={{
backgroundColor: result.custom.badge.bgColor,
color: result.custom.badge.color
}}
>
{result.custom.badge.label}
</span>
</div>
)}
Badge Display Limitsโ
| Badge Type | Max Count | Location | Behavior |
|---|---|---|---|
| Text Badge | 1 | Below product details | First matching condition wins |
| Image Badge | 1 | Top-left of product image | Ships Now or Personalize (same position) |
| Total | 2 | 1 text + 1 image badge |
Text Badges (Priority System)โ
Only one Text Badge displays per product. The first matching condition wins:
| Priority | Badge | Condition | Label Example |
|---|---|---|---|
| 1 | EOY Sale | tags includes 'badge:eoy25clearance' | "Extra 30% off with code CHEERS" |
| 2 | Limited Time Price | ss_tags includes 'limitedtimeprice' | "Limited Time Price" |
| 3 | Out of Stock | No availability AND no waitlist | "Out of Stock" |
| 4 | Waitlist | Waitlist available, no current stock | "Waitlist" |
| 5 | Lightning Deal | tags includes 'badge:lightningdeal' | "Extra 30% off with VIRALDEAL" |
| 6 | Promo Tags | ss_promo_tags has value | Dynamic from promo config |
| 7 | Discontinued | ss_discontinued == 1 | "Discontinues on MM/DD/YYYY" |
| 8 | New Luxe Collection | tags_badge includes 'new luxe collection' | "New Luxe Collection" |
| 9 | Best Seller | ss_bestseller == 1 | "Best Seller" |
| 10 | New Arrival | ss_new_arrival == 1 | "New Arrival" |
Image Badgesโ
Image Badges display independently of the Text Badge priority system and are overlaid on the product image (top-left corner). Since both badges share the same position, only one displays at a time.
Ships Now Image Badgeโ
Displays when products have all sizes ready to ship immediately.
Conditions:
product_typeis'Bridesmaid Dress'- Either:
ss_sizes_ready_to_shipis truthy, ORss_tagsincludes'sstempshipsnowallsizesplpbadge'
- If
ss_variants_filteredexists and is empty, badge is hidden
Styling: Gray background (#e8e2e5), positioned on product image
Personalize Image Badgeโ
Displays when a product can be personalized.
Condition: ss_tags includes 'personalizable'
Styling: Gray background (#e8e2e5), positioned on product image
Promo Tag Configurationโ
Promo tags support custom styling per promotion:
const promoTagClassesConfig = {
BMSMGR: 'suite-looks-tag flex items-center text-darkMauve',
BMSMWP: 'tieoneon-tag flex items-center text-darkSeaGlass',
FRIENDSANDFAMILY23: 'icon-tag faf-tag bg-[#d0b8b6]',
IWD23Promo: 'icon-tag iwd-tag bg-[#d0b8b6]',
PERFECTPAIR: 'perfect-pair-tag flex items-center text-brand-errorText',
$49VELVETDRESSES: 'velvet-tag flex items-center text-darkSeaGlass',
};
To add a new promo tag:
- Add entry to
promoTagClassesConfigwith the promo code as key - Define CSS classes for styling
- Ensure
ss_promo_tagsis populated in SearchSpring
Stylingโ
CSS Filesโ
| File | Purpose |
|---|---|
src/_config/styles/themes/_custom.scss | PLP badge styles |
src/recommendations/email/styles/_custom.scss | Email badge styles |
Text Badge Classesโ
// Base icon tag (used by many Text Badges)
.icon-tag {
border-radius: 9px;
display: flex;
}
// Discontinued badge
.discontinued-tag {
background: #e5b3ac;
}
// Limited time price badge
.limitedprice-tag {
background: #4b5681;
color: #fff;
}
Image Badge Classesโ
// Ships now / Personalize badges (overlaid on image)
// Note: .personliseBadge is the actual class name (typo in codebase)
.ships-now, .personliseBadge {
background: #e8e2e5;
color: #484140;
font-size: 10px;
border-radius: 0 20px 20px 0;
max-width: 75px;
position: absolute;
top: 0;
left: 0;
@media (max-width: 768px) {
font-size: 8px;
max-width: 65px;
}
}
Adding a New Text Badgeโ
-
Add logic in
src/shared/shared/plugins/shared.js:// Add condition check in the priority chain
if (result.attributes.ss_tags?.includes('badge:newbadge')) {
result.custom.badge = {
id: 'newbadge',
label: 'New Badge Label',
class: 'icon-tag new-badge-tag',
};
} -
Add styles in
src/_config/styles/themes/_custom.scss:.new-badge-tag {
background: #yourcolor;
color: #textcolor;
} -
Configure SearchSpring to populate the triggering attribute (e.g.,
ss_tags)
Discontinued Date Displayโ
When a product has a discontinuation date, the Text Badge displays the date:
if (discontinuationDate) {
const date = new Date(discontinuationDate);
badge.label = `Discontinues on ${date.toLocaleDateString('en-US')}`;
}
Badge Data Structureโ
Badges are attached to each search result with the following structure:
interface Badge {
id: string; // Unique identifier (e.g., 'lightningdeal', 'discontinued')
label: string; // Display text
class: string; // CSS classes (Tailwind + custom)
bgColor?: string; // Optional inline background color
color?: string; // Optional inline text color
}
Data Sources (SearchSpring)โ
| Attribute | Type | Purpose |
|---|---|---|
tags | Array | Raw Shopify product tags (e.g., 'badge:eoy25clearance', 'badge:lightningdeal') |
ss_tags | Array | SearchSpring-processed tags (e.g., 'personalizable', 'limitedtimeprice') |
ss_promo_tags | JSON | Promo tag information |
ss_available | Boolean | Stock availability |
ss_waitlist | Boolean | Waitlist availability |
ss_discontinued | Number | Discontinued status (1 = discontinued) |
ss_bestseller | Number | Best seller flag |
ss_new_arrival | Number | New arrival flag |
ss_sizes_ready_to_ship | Boolean | Ships now status |
tags_badge | String | Custom badge tags |
Related Filesโ
static-assets/src/shared/shared/plugins/shared.js- Badge generation logicstatic-assets/src/shared/result/Result.jsx- PLP renderingstatic-assets/src/recommendations/email/Email.jsx- Email renderingstatic-assets/src/_config/styles/themes/_custom.scss- PLP styles