and runs during HTML parse, but hubspotutk is set by js.hs-analytics.net, measured loading at ~834ms. On a first visit the cookie does not exist yet, so a single read returns nothing and the visitor gets no external ID at all — and a first visit is exactly what an ad click is. So poll briefly until HubSpot sets it. The SDK loads lazily (~4.5s) and replays a queue, so an init queued a second or two in still lands before any events are transmitted. */ (function attachExternalId() { var attempts = 0; var MAX_ATTEMPTS = 40; /* 40 x 200ms = 8s, then give up quietly */ var timer = null; function tryAttach() { var raw = getExternalId(); if (!raw) { if (++attempts >= MAX_ATTEMPTS && timer) clearInterval(timer); return; } if (timer) clearInterval(timer); sha256Hex(raw).then(function (hash) { oaiq("init", { user: { external_id_sha256: hash } }); }).catch(function () {}); } tryAttach(); /* returning visitor: immediate */ if (!getExternalId()) timer = setInterval(tryAttach, 200); })(); /* --------------------------------------------------------------------------- 2. Load the SDK off the critical path Whichever comes first: the main thread going idle after load, or the first sign of real user intent. No preconnect on purpose — a TLS handshake during LCP for a script we deliberately deferred is a net loss. Measured on clickpost.ai: load event 3614ms, SDK fetched 4508ms. ------------------------------------------------------------------------ */ var loaded = false; var INTENT = ["pointerdown", "keydown", "scroll"]; function loadSdk() { if (loaded) return; loaded = true; INTENT.forEach(function (t) { removeEventListener(t, loadSdk, { passive: true }); }); var s = document.createElement("script"); s.src = SDK; s.async = true; s.fetchPriority = "low"; document.head.appendChild(s); } INTENT.forEach(function (t) { addEventListener(t, loadSdk, { passive: true, once: true }); }); addEventListener("load", function () { window.requestIdleCallback ? requestIdleCallback(loadSdk, { timeout: 2500 }) : setTimeout(loadSdk, 1500); }, { once: true }); /* --------------------------------------------------------------------------- 3. Conversion id sha256(lowercase(email) + "|" + formId + "|" + ISO-hour), first 20 hex, "lead_" prefix. - email lowercased/trimmed so casing does not fork the id - formId keeps two different forms in the same hour from colliding - the hour bucket is only the server's fallback; the id computed here is sent to the relay verbatim, so the two paths cannot disagree even when a submit straddles an hour boundary Ads Manager's own sample omits event_id. We send it so the pixel event and the relay event collapse into one conversion instead of counting twice. ------------------------------------------------------------------------ */ function buildEventId(email, formId) { var seed = [ String(email || "").trim().toLowerCase(), String(formId || ""), new Date().toISOString().slice(0, 13) ].join("|"); return crypto.subtle.digest("SHA-256", new TextEncoder().encode(seed)).then(function (buf) { var hex = Array.prototype.map.call(new Uint8Array(buf), function (b) { return b.toString(16).padStart(2, "0"); }).join(""); return "lead_" + hex.slice(0, 20); }); } /* Guards a re-fire from the history.pushState that book-a-demo-core.js runs after submit, and from back-navigation onto the same state. */ function firedOnce(id) { try { if (sessionStorage.getItem("oaiq_" + id)) return true; sessionStorage.setItem("oaiq_" + id, "1"); return false; } catch (e) { return false; /* private mode / blocked storage: fire rather than lose it */ } } /* Path 2. keepalive lets the request finish even if the page navigates away. Failures are swallowed deliberately: a reporting call must never surface an error to someone who just submitted a form. The relay hashes the email server-side into user.emails_sha256 and adds the caller's IP and user agent, so this event carries the same match signals the pixel gets for free. */ function sendToRelay(email, formId, eventType, eventId) { try { var payload = { token: RELAY_TOKEN, email: email, form_id: formId || "", event_type: eventType, event_id: eventId, /* verbatim, so both paths always match */ source_url: location.href }; var oppref = getOppref(); if (oppref) payload.oppref = oppref; var externalId = getExternalId(); if (externalId) payload.external_id = externalId; fetch(RELAY_URL, { method: "POST", keepalive: true, headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }).catch(function () {}); } catch (e) {} } /* Capture the email while the form is still on the page. onFormSubmitted does not reliably carry submissionValues, and by then the form may be removed. */ var lastEmail = ""; document.addEventListener("submit", function (e) { var f = e.target; if (!f || !f.querySelector) return; var i = f.querySelector('input[name="email"], input[type="email"]'); if (i && i.value) lastEmail = i.value; }, true); /* Every HubSpot form on the site reports through this one message event, so no module or theme JS needs editing to add coverage. */ window.addEventListener("message", function (e) { var d = e.data; if (!d || d.type !== "hsFormCallback" || d.eventName !== "onFormSubmitted") return; var email = (d.data && d.data.submissionValues && d.data.submissionValues.email) || lastEmail; if (!email) return; /* without an email there is no stable id to dedupe on */ var eventType = EVENT_BY_FORM[d.id] || EVENT_DEFAULT; buildEventId(email, d.id).then(function (id) { if (firedOnce(id)) return; oaiq("measure", eventType, { type: DATA_TYPE }, { event_id: id }); /* path 1 */ sendToRelay(email, d.id, eventType, id); /* path 2 */ }); }); })();

91ÊÓÆµ

See where your logistics stands on automation Start assessment

Home > Blog >

Skincare Outshines Fashion: 2.5x More Orders for Holi 2025 as Consumers Focus on Skin Health

Skincare Outshines Fashion: 2.5x More Orders for Holi 2025 as Consumers Focus on Skin Health

Aparajita Ray
By Aparajita Ray

Ready to ship smarter? Talk to our logistics experts.

Trusted by 600+ brands

In this blog

    The Holi shopping season has always been a test of how efficiently brands and logistics networks can meet the demand for festive essentials. But unlike Diwali or Rakhi, where shopping builds up over weeks, Holi has an extremely short purchase window. Consumers either buy in advance or make last-minute purchases, and this year, that shift has been more pronounced than ever.

    How ClickPost Compiled the Data

    ClickPost analyzed 20.2 million shipments processed across its logistics intelligence platform for Holi 2024 and Holi 2025. The dataset includes 7.6 million shipments from the Holi 2025 period and corresponding data from Holi 2024, allowing for a year-over-year comparison.

    By examining category-wise shipment volumes, delivery performance, and order distribution, ClickPost identified a 2.5X surge in skincare orders compared to fashion, signaling a shift in consumer priorities toward skin protection and post-Holi care over traditional apparel purchases.

    Festive Spending is Up, but Traditional E-Commerce Growth is Modest

    According to projections by the Confederation of All India Traders (CAIT), Holi 2025 business is expected to surpass ₹60,000 crore, a nearly 20% increase from 2024. However, °ä±ô¾±³¦°ì±Ê´Ç²õ³Ù’s data shows that traditional e-commerce shipments grew by just 1.5% compared to Holi 2024. This suggests that while consumers are spending more, they are not necessarily increasing their reliance on traditional online shopping.

    A key reason for this shift is the rise of quick-commerce platforms, which have captured a significant share of last-minute festival demand. Blinkit, Zepto, and Swiggy Instamart recorded record-breaking sales, suggesting that more consumers are opting for hyperlocal, same-day deliveries instead of pre-planned online purchases.

    Another contributing factor is that Holi sees fewer large-scale sales events compared to Diwali and other major festivals. While Diwali shopping is driven by discounts on electronics, home appliances, and fashion through events like the Big Billion Days and the Great Indian Festival, Holi promotions are more targeted and limited in scope.

    Discounts tend to focus on Holi-specific products such as colors, skincare, and festive apparel, rather than across entire product categories. This difference in promotional intensity may partially explain why Holi e-commerce growth remains stable rather than surging like Diwali.

    Quick Commerce vs. Traditional E-Commerce: A Shift in Buying Behavior

    The small increase in e-commerce shipments does not mean demand has flattened—it has simply moved elsewhere. Traditional e-commerce platforms, including leading D2C brands and marketplaces, saw steady but not exceptional growth.

    Meanwhile, quick-commerce platforms saw a surge in Holi-related purchases, fulfilling consumer needs for last-minute essentials such as herbal colors, sweets, and skincare.

    A Bernstein report projects that India’s quick-commerce industry will grow at 75-100% annually, significantly outpacing traditional e-commerce. This aligns with the fact that more consumers are choosing speed over selection, especially for festivals like Holi where the purchase urgency is high.

    Skincare Leads Holi eCommerce- Outpacing Fashion

    °ä±ô¾±³¦°ì±Ê´Ç²õ³Ù’s data shows a clear shift in what consumers prioritized for Holi 2025. Skincare and cosmetics orders were 2.5 times higher than fashion, marking a significant change from previous years when apparel, particularly white ethnic wear, was among the top-selling categories.

    The surge in skincare demand can be attributed to two key factors. First, greater awareness around skin protection from Holi colors has led to higher sales of SPF products, color-proof moisturizers, and post-Holi skin recovery items. Second, beauty and skincare brands have been more aggressive in Holi-specific marketing, promoting their products as festival essentials rather than just optional self-care purchases.

    Fashion, while still a key Holi category, did not see comparable growth. This could be due to consumers shifting fashion purchases to offline retail, or quick-commerce platforms not yet being fully optimized for fashion fulfillment.

    Regional Demand and Logistics Performance

    Last year, Tier 3 cities accounted for 85% of all Holi e-commerce shipments, reinforcing that regional demand fuels much of the festival’s online sales. While we await a full breakdown for 2025, °ä±ô¾±³¦°ì±Ê´Ç²õ³Ù’s shipment data suggests this trend is likely to continue.

    From a logistics perspective, delivery speeds slowed slightly by 1.2% during the Holi period compared to pre-Holi shipments. However, non-delivery rates actually improved, suggesting that logistics networks adapted well to the short buying window. This is a strong indication that fulfillment strategies have matured, ensuring that orders are delivered on time despite demand spikes.

    What This Means for Brands & Logistics Providers?

    Holi 2025 reinforces that e-commerce behavior is evolving. While consumers are spending more, they are also shifting how they buy. The biggest takeaways from this year’s trends are:-

    1. Quick commerce is no longer just for groceries and daily essentials. Its ability to fulfill festival-driven demand at scale is a direct challenge to traditional e-commerce.
    2. Brands selling Holi-specific products must rethink distribution strategies. Skincare brands, for instance, saw massive demand, but their fulfillment models may need to shift towards instant delivery to keep up.
    3. Regional demand continues to grow, but logistics efficiency is key. If last-mile delivery speeds can be improved further, brands can serve both metro and non-metro customers more effectively during short-window festivals like Holi.
    4. Holi promotions differ from other major festivals, impacting sales trends. Unlike Diwali, which sees extensive discounting across multiple categories, Holi discounts remain product-specific and narrowly focused, influencing overall sales momentum in traditional e-commerce.

    Conclusion

    As the lines between traditional e-commerce and quick-commerce continue to blur, brands must adapt to an environment where speed is as critical as selection. The post-purchase experience—timely deliveries, lower return rates, and seamless fulfillment—will determine how well businesses retain festival customers in the years ahead.

    Source:

    The Logistics Automation Platform for E-commerce

    Momentum Leader - G2 Users Most Likely To Recommend - G2 Best Results Mid-Market - G2
    . window.disableHubSpotCookieBanner = true; function killNative() { var n = document.getElementById("hs-eu-cookie-confirmation"); if (n && n.parentNode) { n.parentNode.removeChild(n); return true; } return false; } killNative(); if (window.MutationObserver) { var mo = new MutationObserver(function () { killNative(); }); mo.observe(document.documentElement, { childList: true, subtree: true }); setTimeout(function () { mo.disconnect(); }, 15000); } var COOKIE = "cp_cookie_consent"; var EU = ["at","be","bg","hr","cy","cz","dk","ee","fi","fr","de","gr","hu","ie","it","lv","lt","lu","mt","nl","pl","pt","ro","sk","si","es","se","gb","uk","is","li","no","ch"]; function readCookie(nm) { var m = document.cookie.match(new RegExp("(?:^|; )" + nm + "=([^;]*)")); return m ? decodeURIComponent(m[1]) : null; } function writeCookie(nm, val, days) { var d = new Date(); d.setTime(d.getTime() + (days * 864e5)); document.cookie = nm + "=" + encodeURIComponent(val) + ";expires=" + d.toUTCString() + ";path=/;SameSite=Lax" + (location.protocol === "https:" ? ";Secure" : ""); } function stored() { var raw = readCookie(COOKIE); if (!raw) return null; try { var o = JSON.parse(raw); if (typeof o.analytics === "boolean") return o; } catch (e) {} return null; } function apply(state, revoke) { window._hsp = window._hsp || []; window._hsp.push(["setHubSpotConsent", { analytics: !!state.analytics, advertisement: !!state.advertisement, functionality: !!state.functionality }]); if (revoke && !state.analytics && !state.advertisement && !state.functionality) { window._hsp.push(["revokeCookieConsent"]); } window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: "cp_cookie_consent", cp_consent_analytics: !!state.analytics, cp_consent_advertisement: !!state.advertisement, cp_consent_functionality: !!state.functionality }); document.documentElement.setAttribute("data-cp-consent", "set"); } function inScope(banner) { if (banner.getAttribute("data-scope") !== "eu_only") return true; var geo = (document.body.getAttribute("data-geo_location") || "").toLowerCase(); if (!geo) return true; return EU.indexOf(geo) !== -1; } function init(banner) { var days = parseInt(banner.getAttribute("data-days"), 10) || 180; var prefs = banner.querySelector("[data-cpcb-prefs]"); var compact = banner.querySelector('[data-cpcb-actions="compact"]'); var expanded = banner.querySelector('[data-cpcb-actions="expanded"]'); var toggles = banner.querySelectorAll("[data-cpcb-toggle]"); function show() { banner.hidden = false; requestAnimationFrame(function () { banner.classList.add("is-visible"); }); } function hide() { banner.classList.remove("is-visible"); setTimeout(function () { banner.hidden = true; }, 300); } function collapse() { if (!prefs) return; prefs.hidden = true; if (expanded) expanded.hidden = true; if (compact) compact.hidden = false; } function expand() { if (!prefs) return; prefs.hidden = false; if (compact) compact.hidden = true; if (expanded) expanded.hidden = false; } function paint(state) { Array.prototype.forEach.call(toggles, function (t) { var key = t.getAttribute("data-cpcb-toggle"); if (key === "necessary") { t.setAttribute("aria-checked", "true"); return; } t.setAttribute("aria-checked", state[key] ? "true" : "false"); }); } function fromToggles() { var state = { analytics: false, advertisement: false, functionality: false }; Array.prototype.forEach.call(toggles, function (t) { var key = t.getAttribute("data-cpcb-toggle"); if (key in state) state[key] = t.getAttribute("aria-checked") === "true"; }); return state; } function commit(state, revoke) { writeCookie(COOKIE, JSON.stringify({ analytics: !!state.analytics, advertisement: !!state.advertisement, functionality: !!state.functionality, v: 1, ts: Date.now() }), days); apply(state, revoke); hide(); } Array.prototype.forEach.call(toggles, function (t) { if (t.disabled) return; t.addEventListener("click", function () { t.setAttribute("aria-checked", t.getAttribute("aria-checked") === "true" ? "false" : "true"); }); }); banner.addEventListener("click", function (e) { if (!e.target || !e.target.closest) return; var btn = e.target.closest("[data-cpcb-action]"); if (!btn) return; var action = btn.getAttribute("data-cpcb-action"); if (action === "customise") { expand(); return; } if (action === "accept") { commit({ analytics: true, advertisement: true, functionality: true }, false); return; } if (action === "reject") { commit({ analytics: false, advertisement: false, functionality: false }, true); return; } if (action === "save") { commit(fromToggles(), true); return; } }); var existing = stored(); if (existing) { apply(existing, false); paint(existing); collapse(); } else if (!inScope(banner)) { // Out of the consent-required region: implied consent, banner never shown. commitSilently(); } else { collapse(); show(); } function commitSilently() { var all = { analytics: true, advertisement: true, functionality: true }; writeCookie(COOKIE, JSON.stringify({ analytics: true, advertisement: true, functionality: true, v: 1, ts: Date.now(), implied: true }), days); apply(all, false); } // Public re-open hook for a footer "Cookie settings" link. window.cpCookieBanner = window.cpCookieBanner || {}; window.cpCookieBanner.open = function () { var s = stored() || { analytics: false, advertisement: false, functionality: false }; paint(s); expand(); show(); }; } function boot() { var banners = document.querySelectorAll("[data-cpcb]"); if (!banners.length) return; init(banners[0]); document.addEventListener("click", function (e) { if (!e.target || !e.target.closest) return; var trigger = e.target.closest("[data-cp-cookie-settings]"); if (!trigger) return; e.preventDefault(); if (window.cpCookieBanner && window.cpCookieBanner.open) window.cpCookieBanner.open(); }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } })();