Search for products, concerns and keywords.


Your Brand Consultant Agreement has been successfully renewed.
There was a problem processing your Brand Consultant Agreement renewal. Please try again.
There was a system error. Please try again.
There was an issue adding this product. Please refresh the page and try again
You're saving 10% on your entire order, including subscription orders and one-time purchases!

Be a product of the product! Schedule convenient, monthly deliveries of your favorite R+F products at the discounted Consultant price.

Join PC Perks for Free
  • Free gift ($50+ value) with 2nd qualifying order + exclusive offers
  • Fully flexible subscription: Choose delivery frequency and delay or cancel anytime before shipment
Item has been added to your bag.
This field is required.
Home | RECHARGE Ultra Boost Moisturizing Treatment
  • RECHARGE Ultra Boost Moisturizing Treatment
  • RCTT050-lifestyle-1168x1168-tablet-1.jpg

RECHARGE Ultra Boost Moisturizing Treatment

$81.00

This item is part of Recharge Regimen

Save 20% when you buy a regimen versus purchasing each product individually.

60 Day Money Back Guarantee

Don't love it? It's on us. Learn More

60 Day Money Back Guarantee

Don't love it? It's on us. Learn More

Boost skin's luminance. Our fast-absorbing gel cream restores skin's moisture + defends against visible signs of stress.

Recommended Usage: Twice daily, in the AM + PM
Size: 50 mL / 1.69 Fl. Oz. U.S.

DETAILS

What it is: A weightless treatment with nutrient-rich Electri5 Complex that instantly moisturizes + softens skin as it defends from daily environmental aggressors. Non-comedogenic.

Why you need it: Your body's most important antioxidant starts to diminish in your early 20s, which can lead to dull, dehydrated skin and more. Boost skin's energy to reveal a healthy, vibrant-looking complexion.

For best results, use the full Recharge Regimen.

ITEM NUMBER: RCTT050

KEY CONCERNS

Unhealthy-Looking, Tired + Stressed Skin, Dullness, Uneven + Rough Texture, Dryness, Environmental Pollutants

SKIN TYPE

Suitable for all skin types

KEY BENEFITS

Instantly moisturizes, softens skins and defends against visible signs of stress for healthy, vibrant-looking skin

INGREDIENTS

Proprietary Technology + Key Ingredients
  • Proprietary Electri5 Complex

    Act like a powerful, nutrient-rich vitamin to supercharge and visibly improve skin
  • RFA+

    Balances skin’s equilibrium and boosts skin’s energy to defend against visible signs of stress
  • Glyceryl Glucoside

    Defends skin against pollutants to reveal healthy-looking skin
View All Ingredients

RESULTS

  • 95%

    had more resilient, bouncy skin*
  • 89%

    instantly had less oily skin*
  • 89%

    saw overall healthier-looking skin**
  • 89%

    saw smoother skin texture**
  • 85%

    saw less dull, blotchy skin**
View Full Study

HOW TO USE

Use twice daily in the AM + PM, avoiding the eye area.
  1. Dispense 2-3 pumps in your palm and massage onto your face until absorbed using fingertips.
  2. Do not rinse off.
 

HOW TO USE

Use twice daily in the AM + PM, avoiding the eye area.
  1. Dispense 2-3 pumps in your palm and massage onto your face until absorbed using fingertips.
  2. Do not rinse off.
 

View Less View More

Reviews

Common questions about the Rodan + Fields

RECHARGE Ultra Boost Moisturizing Treatment

Why do I need to use the RECHARGE Regimen?

We're all aging everyday even if it's not visible on the skin. In your early 20s, shifts in your body's metabolism make you more vulnerable to everyday stressors — environmental, emotional and physical — and can accelerate the aging process beneath the skin's surface. Early signs of aging will appear sooner and more dramatically for those who do not care for and protect their skin properly.

How does the RECHARGE Regimen work?

Based on Multi-Med Therapy (the right ingredients in the right formulations applied in the right order), RECHARGE is a comprehensive skincare Regimen that acts as a nutrient-rich super vitamin to boost skin's defenses against environmental aggressors. RECHARGE is clinically-demonstrated to visibly improve skin from the first use while defending against visible signs of stress for hydrated, glowing, healthy-looking skin that is here to stay. The secret to RECHARGE is R+F's proprietary Electri5 Complex which is a unique blend of our breakthrough RFA+ antioxidant technology coupled with electrolytes, peptides, prebiotics and superfruits.

Do I need to use all the RECHARGE Regimen steps to get results?

Yes. Each step of the RECHARGE Regimen was designed to build upon the last. To boost and maintain your healthiest-looking skin, the formulas must be used in combination. Skipping any step could hinder achieving maximum results.

How long should I use the RECHARGE Regimen?

There is no limit to how long you can use the RECHARGE Regimen. However, as your skin and skincare concerns continue to evolve, we recommend transitioning to one of our other skincare Regimens. Rodan + Fields now has a Regimen for every stage of life and skin need.

• REDEFINE Regimen for the Appearance of Lines, Pores + Loss of Firmness
• Reverse Brightening Regimen for the Appearance of Discoloration + Uneven Skin Tone
• SOOTHE Regimen for Visible Redness, Dryness + Sensitivity
• Regimen for Adult Acne + the Visible Signs of Aging
• SPOTLESS Regimen for Teen + Young Adult Acne
• RECHARGE Regimen for Balancing, Boosting + Defending Healthy-Looking Skin

What is Electri5 complex?

Rodan + Fields proprietary Electri5 Complex, a unique blend of breakthrough RFA+ antioxidant technology coupled with electrolytes, peptides, prebiotics and superfruits. In perfect combination, these ingredients act like a powerful, nutrient rich vitamin to supercharge and visibly improve skin from first use!

Can I use the RECHARGE Regimen while pregnant or nursing?

If you are pregnant or nursing, we recommend consulting your doctor about any concerns you may have regarding your skincare or cosmetic routine. To better assist your doctor, view a full list of our products and ingredients.

Common questions about the Rodan + Fields

RECHARGE Ultra Boost Moisturizing Treatment

Why do I need to use the RECHARGE Regimen?

We're all aging everyday even if it's not visible on the skin. In your early 20s, shifts in your body's metabolism make you more vulnerable to everyday stressors — environmental, emotional and physical — and can accelerate the aging process beneath the skin's surface. Early signs of aging will appear sooner and more dramatically for those who do not care for and protect their skin properly.

How does the RECHARGE Regimen work?

Based on Multi-Med Therapy (the right ingredients in the right formulations applied in the right order), RECHARGE is a comprehensive skincare Regimen that acts as a nutrient-rich super vitamin to boost skin's defenses against environmental aggressors. RECHARGE is clinically-demonstrated to visibly improve skin from the first use while defending against visible signs of stress for hydrated, glowing, healthy-looking skin that is here to stay. The secret to RECHARGE is R+F's proprietary Electri5 Complex which is a unique blend of our breakthrough RFA+ antioxidant technology coupled with electrolytes, peptides, prebiotics and superfruits.

Do I need to use all the RECHARGE Regimen steps to get results?

Yes. Each step of the RECHARGE Regimen was designed to build upon the last. To boost and maintain your healthiest-looking skin, the formulas must be used in combination. Skipping any step could hinder achieving maximum results.

How long should I use the RECHARGE Regimen?

There is no limit to how long you can use the RECHARGE Regimen. However, as your skin and skincare concerns continue to evolve, we recommend transitioning to one of our other skincare Regimens. Rodan + Fields now has a Regimen for every stage of life and skin need.

• REDEFINE Regimen for the Appearance of Lines, Pores + Loss of Firmness
• Reverse Brightening Regimen for the Appearance of Discoloration + Uneven Skin Tone
• SOOTHE Regimen for Visible Redness, Dryness + Sensitivity
• Regimen for Adult Acne + the Visible Signs of Aging
• SPOTLESS Regimen for Teen + Young Adult Acne
• RECHARGE Regimen for Balancing, Boosting + Defending Healthy-Looking Skin

What is Electri5 complex?

Rodan + Fields proprietary Electri5 Complex, a unique blend of breakthrough RFA+ antioxidant technology coupled with electrolytes, peptides, prebiotics and superfruits. In perfect combination, these ingredients act like a powerful, nutrient rich vitamin to supercharge and visibly improve skin from first use!

Can I use the RECHARGE Regimen while pregnant or nursing?

If you are pregnant or nursing, we recommend consulting your doctor about any concerns you may have regarding your skincare or cosmetic routine. To better assist your doctor, view a full list of our products and ingredients.

What is RFA+ complex?

RFA+ is a groundbreaking antioxidant technology from Kyoto University in Japan that balances skin's equilibrium, boosts skin's energy to defend against the visible signs of stress for your healthiest, most vibrant-looking skin. It is a combination of Glutathione technology + vitamin E exclusive to R+F.

Can the RECHARGE Regimen be used on sensitive skin?

For sensitive skin, we recommend first using our Soothe Regimen to help moisturize, strengthen, calm and nourish your skin.

Does the RECHARGE Regimen address anti-aging concerns?

The RECHARGE Regimen was specifically designed to defend against the early signs of visible stress - dullness, blotchiness, dryness or tired-looking skin. If you start to notice more advanced signs of aging, we recommend you use one of our anti-aging Regimens - Redefine Regimen for the appearance of fine lines, wrinkles and loss of firmness or Reverse Brightening Regimen for the appearance of discoloration and uneven skin tone.

Can the RECHARGE Regimen be used on acne-prone skin?

The RECHARGE Regimen is non-comedogenic and non-acnegenic, meaning it will not clog pores or cause breakouts. However, to treat acne breakouts we recommend using one of our acne fighting Regimens — UNBLEMISH to gently and effectively address acne and aging concerns or SPOTLESS to eliminate current acne and prevent future breakouts for teen and young adult skin.

(function() { 'use strict'; // ============================================ // CONFIGURATION - EDIT THESE VALUES // ============================================ const marketingCards = [ // ============================================ // MARKETING CARDS - EVERGREEN - "Lash Day Offer" // ============================================ { // URLS to match for immediate render urlMatches: ['beauty-enhancements','lash-serum-and-eyebrow-tint'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'YOUR LASHES.
BUT BETTER.
', bodyText: 'Celebrate National Lash Day with a boost. Get 20% off Lash Boost + a FREE Mini Eye Cream, for a limited time.', ctaText: 'USE CODE LASHDAY', ctaHref: '/shop/r-f-lash-boost/p/ENHLSH01', cardHref: '/shop/r-f-lash-boost/p/ENHLSH01', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/LASH-DAY-marketing-module-horizontal-image.jpg?context=bWFzdGVyfGltYWdlc3wxMTMwOTh8aW1hZ2UvanBlZ3xhRGczTDJneFppOHlPRFExTVRReE1UY3lNakkzTUM5TVFWTklMVVJCV1MxdFlYSnJaWFJwYm1jdGJXOWtkV3hsWDJodmNtbDZiMjUwWVd4ZmFXMWhaMlV1YW5CbnxhNTZkMTEyODgxNzdhM2NkNGQxODNkYmRjNWRkNGUyZDVjYjNmYjRlYWQxZjc0NjRhMGJjMjZjZjI5N2Y2YTI0', backgroundColor: '#FFFFFF', // Used only if backgroundImage is null copyBackgroundColor: '#FFFFFF', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Pure C Promo MC" // ============================================ { // URLS to match for immediate render urlMatches: ['best-sellers','redefine','skin-care-regimens'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'LIMITED-TIME: PURE C EXCLUSIVE OFFERS', bodyText: 'Pair with Active Hydration Serum and save $45 or buy Pure C, get a complimentary Hydra Mask ($54 Value)', ctaText: 'Shop Now', ctaHref: '/category/face-serums', cardHref: '/category/face-serums', disclaimerText: 'Valid thru 2/28/26. See Terms & Conditions', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Pure-C-Promo-Marketing-Module.jpg?context=bWFzdGVyfGltYWdlc3w2NTk0MHxpbWFnZS9qcGVnfGFESXdMMmhoWmk4eU9ETTVOems1TnpjeE9UVTRNaTlRZFhKbExVTXRVSEp2Ylc4dFRXRnlhMlYwYVc1bkxVMXZaSFZzWlM1cWNHY3xhNmFmZWY2YjU3MzM5ZWY2NWNlN2Q5Njk1MWFjYTY1MzE0MWI4NzQ3OWY1YWUyNTM0NDY4YzUwMzcyYzcwY2Mz', backgroundColor: '#FFFFFF', // Used only if backgroundImage is null copyBackgroundColor: '#FFFFFF', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Pure C Evergreen MC" // ============================================ { // URLS to match for immediate render urlMatches: ['face-serums','anti-aging-skin-care'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'NEW PURE C SERUM', bodyText: 'Activate your skin’s longevity for firmer, smoother, brighter skin...now and for years to come', ctaText: 'Learn More', ctaHref: '/discover/purec', cardHref: '/discover/purec', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Pure-C-Evergreen-Marketing-Module.jpg?context=bWFzdGVyfGltYWdlc3w5MjQxOXxpbWFnZS9qcGVnfGFEVXhMMmhoTlM4eU9ETTVOems1TnpRMU56UXpPQzlRZFhKbExVTXRSWFpsY21keVpXVnVMVTFoY210bGRHbHVaeTFOYjJSMWJHVXVhbkJufDNkZTgzNTUzYTFjY2QwMjY2OWVlZjljODYwZmNjYWY5YzRmNGFjNWE2Y2I3YjM4YjczNTdjODhmOTQzZDcwMDY', backgroundColor: '#FFFFFF', // Used only if backgroundImage is null copyBackgroundColor: '#FFFFFF', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Money Back Guarantee" // ============================================ { // URLS to match for immediate render urlMatches: ['exfoliants','eye-creams-and-treatments','neck-and-decollete','reverse','soothe','unblemish'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'Love it or get your money back.', bodyText: 'We stand behind our science, formulas + results with a 60-Day Money Back Guarantee.', ctaText: 'Learn More', ctaHref: '/satisfaction-guarantee', cardHref: '/satisfaction-guarantee', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/60-day-Guarantee.jpg?context=bWFzdGVyfGltYWdlc3wyNDc0OTd8aW1hZ2UvanBlZ3xhREppTDJnek1TOHlPRE01TnprNU5qRTBOamN4T0M4Mk1DMWtZWGt0UjNWaGNtRnVkR1ZsTG1wd1p3fDM1ZDU3NGEwZDllNWMxZDUwYzk1NDJhZjMwNGZkM2Y5NGEwMmM3NTQ2MzhjYTI0ZDk2NWQ4ZjJlOTY2NTJmYWE', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "#1 Female Dermatologist Founded Skincare Brand" // ============================================= { // URLS to match for immediate render urlMatches: ['acne-pores-blackheads-skin-care','dry-skin-care','skin-care-essentials','face-moisturizers','lip-care-and-color','sensitive-skin-care','sun-protection','toners','uneven-skin-tone-and-dark-marks-skin-care'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: '#1 Female Dermatologist Founded Skincare Brand in the U.S.*', bodyText: '', ctaText: 'Learn More', ctaHref: '/nx/our-story', cardHref: '/nx/our-story', disclaimerText: '*Source Euromonitor Int’l Ltd. 2024; See rodanandfields.com for details.', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Female-Derm.jpg?context=bWFzdGVyfGltYWdlc3wyNDQ2MTR8aW1hZ2UvanBlZ3xhR1k1TDJnellTOHlPRE01TnprNU5qUXdPRGcyTWk5R1pXMWhiR1V0UkdWeWJTNXFjR2N8NDc0NTdhYzliNzNhMTA3ZGJkYzc5NzVmNjMzNzcyMGUwYzE5OGQzMDk3MDE3ZWRhNTk2NTM3ZjZlZGZhNjdjMQ', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Rodan + Fields is the #1 Premium Lash Serum" // ============================================= { // URLS to match for immediate render urlMatches: [], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'Rodan + Fields is the #1 Premium Lash Serum Brand in the US in 2024*', bodyText: '', ctaText: '', ctaHref: '', cardHref: '', disclaimerText: '*Source Euromonitor International Limited; Custom research conducted June-Aug 2025, retail value RSP terms; all channels; Lash Serum including Lash Serum products sold as part of Sets and Kits', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Lash-Boost-MC-Image.jpg?context=bWFzdGVyfGltYWdlc3wyMDE1Mjd8aW1hZ2UvanBlZ3xhRFJsTDJneU1DOHlPRE01TnprNU5UZzRORFUzTkM5TVlYTm9MVUp2YjNOMExVMURMVWx0WVdkbExtcHdad3w2MTVjMTdmN2Q2MDJlYmIzMzhmOWQ2OTg0MmRlNTFiODg5N2Q5OTBhNDFlODQwMmNjODliMzM3Yjk3NGJiNjIz', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Klarna" // ============================================= { // URLS to match for immediate render urlMatches: ['regimen-sets','rf-paired-multi-action-regimens','skin-care-tools-and-accessories'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'Buy now. Pay later.', bodyText: 'Select Klarna at checkout to split your purchase into 4 interest-free payments.', ctaText: '', ctaHref: '', cardHref: '', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Klarna.jpg?context=bWFzdGVyfGltYWdlc3wzMTE3NnxpbWFnZS9qcGVnfGFETmlMMmc1TVM4eU9ETTVOems1T1RFMk1UTTNOQzlMYkdGeWJtRXVhbkJufDUwMzJkNzBjNzRjZmMxYzc2MjE5NWEyNjIwOTJmYzg5ZDE1NjQ1Y2U4MDQ3ZTg2OTI3ZjIxMzE1OGU3OGE2NWI', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' } ]; // ============================================ // MODULE HTML GENERATOR // ============================================ function generateModuleHTML(cfg) { const alignMap = { left: 'flex-start', center: 'center', right: 'flex-end' }; const safeAlign = ['left','center','right'].includes(cfg.copyAlign) ? cfg.copyAlign : 'center'; const bgStyle = cfg.backgroundImage ? `background: url('${cfg.backgroundImage}') center/cover no-repeat;` : `background: ${cfg.backgroundColor}`; const shadowStyle = cfg.textShadowEnabled ? 'text-shadow: 0 1px 2px rgba(0,0,0,0.6);' : ''; // Split Image Half Layout if (cfg.splitImageHalf) { const splitImageStyle = `${cfg.backgroundImage ? `--split-image-url: url('${cfg.backgroundImage}');` : ''}`; const cardAttr = cfg.cardHref ? `data-card-href="${cfg.cardHref}"` : ''; const cardClass = cfg.cardHref ? ' rf-card-clickable' : ''; return `

${cfg.titleText.replace(/\n/g, '
')}

${cfg.bodyText ? `

${cfg.bodyText}

` : ''} ${cfg.ctaText && cfg.ctaText.trim() ? `${cfg.ctaText}` : ''} ${cfg.disclaimerText ? `
${cfg.disclaimerText}
` : ''}
`; } // Default horizontal layout const cardAttr = cfg.cardHref ? `data-card-href="${cfg.cardHref}"` : ''; const cardClass = cfg.cardHref ? ' rf-card-clickable' : ''; return `

${cfg.titleText.replace(/\n/g, '
')}

${cfg.bodyText ? `

${cfg.bodyText}

` : ''} ${cfg.ctaText && cfg.ctaText.trim() ? `${cfg.ctaText}` : ''} ${cfg.disclaimerText ? `
${cfg.disclaimerText}
` : ''}
`; } // PDP detection helper function isPDP() { try { const path = (window.location && window.location.pathname) || ''; // PDP URLs include "/p/" followed by a code return path.includes('/p/'); } catch (e) { return false; } } // Return cards whose urlMatches match a full path segment (not substring) function getActiveCards() { const href = (window.location && window.location.href || '').toLowerCase(); const path = (window.location && window.location.pathname || '').toLowerCase(); const segments = path.split('/').filter(Boolean); // path parts without empty strings const matchesSegment = (needle) => { if (!needle) return false; const n = String(needle).toLowerCase(); // exact segment match, or common category patterns return segments.includes(n) || path.endsWith('/' + n) || path.includes('/shop/' + n + '/') || href.includes('cgid=' + encodeURIComponent(n)); }; return marketingCards.filter(card => Array.isArray(card.urlMatches) && card.urlMatches.some(matchesSegment)); } // ============================================ // PRODUCT DETECTION // ============================================ let injected = false; function filterProductElements(elements) { return elements.filter(el => { const tag = el.tagName ? el.tagName.toLowerCase() : ''; if (tag === 'button' || tag === 'a') return false; const role = (el.getAttribute && el.getAttribute('role')) || ''; if (role === 'button' || role === 'link') return false; if (el.hasAttribute && el.hasAttribute('data-copilot-module')) return false; if (el.closest && el.closest('.add-to-cart, .product-cta, .product-actions, .pdp-add-to-cart, .quickbuy')) return false; return true; }); } function findProducts() { const selectors = [ '[data-product-code]', '[data-product-id]', '.product-item', '.product-card', '.product-tile', '.product', '.js-product', 'article.product', '.product-grid-item', '.product-list-item' ]; for (let selector of selectors) { const elements = document.querySelectorAll(selector); if (elements.length > 0) { console.log(`Found ${elements.length} products using: ${selector}`); return filterProductElements(Array.from(elements)); } } console.warn('No products found'); return []; } function getProductCode(el) { return el.getAttribute('data-product-code') || el.getAttribute('data-product-id') || el.getAttribute('data-sku') || el.querySelector('[data-product-code]')?.getAttribute('data-product-code') || el.querySelector('[data-product-id]')?.getAttribute('data-product-id') || el.querySelector('a[href*="/shop/"]')?.href.split('/p/')[1]?.split('?')[0] || null; } // ============================================ // INJECTION LOGIC // ============================================ function injectModule() { if (injected) return; // Guard: never inject on PDPs if (isPDP()) { console.warn('PDP detected; skipping marketing card injection.'); return; } const cards = getActiveCards(); if (!cards || cards.length === 0) { console.warn('No marketing card configured for this URL'); return; } // Only consider products inside .mdc-layout-grid__inner if present let products = []; const gridInner = document.querySelector('.mdc-layout-grid__inner'); if (gridInner) { // Find all product elements inside the grid products = filterProductElements(Array.from(gridInner.querySelectorAll('[data-product-code], [data-product-id], .product-item, .product-card, .product-tile, .product, .js-product, article.product, .product-grid-item, .product-list-item'))); } else { products = findProducts(); } if (products.length === 0) return; console.log(`${cards.length} marketing card(s) matched this URL`); // Log all found product codes and positions for debugging console.log('Product codes and positions found:'); products.forEach((p, i) => { const pos = p.getAttribute('data-position'); const code = getProductCode(p); console.log(` Index ${i + 1} | Position: ${pos} | Code: ${code || 'N/A'}`); }); // Try to inject each matching card let anyInjected = false; cards.forEach(card => { let placed = false; // Placement logic if (!placed && card.placement) { if (card.placement.toLowerCase() === 'start' && products.length > 0) { console.log('Inserting module at START (before first product)'); insertModule(products[0], 'before', card); placed = true; } else if (card.placement.toLowerCase() === 'end' && products.length > 0) { console.log('Inserting module at END (after last product)'); insertModule(products[products.length - 1], 'after', card); placed = true; } } // Fallbacks: by product code or position if (!placed) { for (let i = 0; i < products.length; i++) { const code = getProductCode(products[i]); if (card.insertAfterProductCode && code === card.insertAfterProductCode) { console.log(`Inserting module AFTER product code: ${code}`); insertModule(products[i], 'after', card); placed = true; break; } if (card.insertBeforeProductCode && code === card.insertBeforeProductCode) { console.log(`Inserting module BEFORE product code: ${code}`); insertModule(products[i], 'before', card); placed = true; break; } } } if (!placed && card.insertAtPosition) { let targetProduct = null; // Try to find by data-position attribute first targetProduct = Array.from(products).find(p => parseInt(p.getAttribute('data-position')) === card.insertAtPosition ); // If not found, fallback to Nth product in the array (1-based) if (!targetProduct && products.length >= card.insertAtPosition) { targetProduct = products[card.insertAtPosition - 1]; } // If still not found, fallback to last product in gridInner if (!targetProduct && products.length > 0) { targetProduct = products[products.length - 1]; } if (targetProduct) { console.log(`Inserting module after product (insertAtPosition=${card.insertAtPosition})`); insertModule(targetProduct, 'after', card); placed = true; } } if (!placed) { console.warn(`Target not found for card. Check insertAfterProductCode, insertBeforeProductCode, or insertAtPosition configuration.`); } else { anyInjected = true; } }); if (anyInjected) { injected = true; // Ensure any end-placed cards are positioned after the latest product set repositionEndCards(); } } function insertModule(target, position, cardConfig) { const wrapper = document.createElement('div'); wrapper.innerHTML = generateModuleHTML(cardConfig).trim(); const base = target.closest && target.closest('[data-product-code], [data-product-id], .product-item, .product-card, .product-tile, .product, .js-product, article.product, .product-grid-item, .product-list-item') || target; const baseTag = (base.tagName || '').toLowerCase(); const safeTag = (baseTag === 'button' || baseTag === 'a') ? 'div' : (baseTag || 'div'); const classList = (base.className || '') .split(/\s+/) .filter(Boolean) .filter(c => !/(^|-)btn($|-)|button|cta|add-to-cart|purchase|subscribe|link/i.test(c)) .join(' '); const container = document.createElement(safeTag); if (classList) container.className = classList; container.setAttribute('data-copilot-module', 'true'); if (cardConfig && cardConfig.placement) { container.setAttribute('data-copilot-placement', String(cardConfig.placement).toLowerCase()); } container.appendChild(wrapper.firstElementChild); if (position === 'after') { base.parentNode.insertBefore(container, base.nextSibling); } else { base.parentNode.insertBefore(container, base); } // Make entire card clickable if data-card-href is present const clickable = container.querySelector('.rf-card-clickable[data-card-href]'); if (clickable) { const href = clickable.getAttribute('data-card-href'); clickable.setAttribute('role', 'link'); clickable.setAttribute('tabindex', '0'); const navigate = () => { try { window.location.assign(href); } catch(e) { window.location.href = href; } }; clickable.addEventListener('click', (e) => { const insideAnchor = e.target.closest('a'); if (insideAnchor) return; // allow inner links like CTA/disclaimer navigate(); }); clickable.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); navigate(); } }); } console.log('Marketing module injected successfully!'); } // Reposition any cards configured with placement: 'End' after dynamic loads function repositionEndCards() { const endCards = Array.from(document.querySelectorAll('[data-copilot-module="true"][data-copilot-placement="end"]')); if (endCards.length === 0) return; // Determine current product list inside grid const gridInner = document.querySelector('.mdc-layout-grid__inner'); const productSelector = '[data-product-code], [data-product-id], .product-item, .product-card, .product-tile, .product, .js-product, article.product, .product-grid-item, .product-list-item'; let products = []; if (gridInner) { products = Array.from(gridInner.querySelectorAll(productSelector)); } else { products = Array.from(document.querySelectorAll(productSelector)); } products = products.filter(el => !el.hasAttribute('data-copilot-module')); if (products.length === 0) return; const lastProduct = products[products.length - 1]; endCards.forEach(card => { if (lastProduct.nextSibling !== card) { try { lastProduct.parentNode.insertBefore(card, lastProduct.nextSibling); } catch (e) {} } }); } function isModulePresent() { return document.querySelector('[data-copilot-module="true"]') !== null; } // ============================================ // INITIALIZATION - IMMEDIATE LOAD // ============================================ function init() { injectModule(); // Quick retries for fast page load if (!injected) { setTimeout(injectModule, 100); setTimeout(injectModule, 300); setTimeout(injectModule, 500); setTimeout(injectModule, 1000); } } // Run immediately init(); // Also run on DOMContentLoaded as backup if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } // Watch for dynamically loaded products const observer = new MutationObserver(() => { clearTimeout(window.moduleInjectionTimeout); window.moduleInjectionTimeout = setTimeout(() => { if (!isModulePresent()) { injected = false; injectModule(); } repositionEndCards(); }, 120); }); // Start observing immediately const startObserver = () => { const container = document.querySelector('.product-grid, .product-list, .products, main, body'); if (container) { observer.observe(container, { childList: true, subtree: true }); } }; startObserver(); setTimeout(startObserver, 500); })();