Shop Men's Mustard Corduroy Bucket Hat Online. | The Bear House
Express delivery across 15k+ pincodes in India
TRUSTED BY 1.5M+ CUSTOMERS ACROSS INDIA
FREE SHIPPING ON PREPAID ORDERS ACROSS INDIA
Cart
Your cart is currently empty.
Men's Mustard Corduroy Bucket Hat by The Bear House
Men's Mustard Corduroy Bucket Hat by The Bear House
Men's Mustard Corduroy Bucket Hat by The Bear House
Men's Mustard Corduroy Bucket Hat by The Bear House
Men's Mustard Corduroy Bucket Hat by The Bear House

Kimoc

Men's Mustard Corduroy Bucket Hat
₹1,199 Regular price Sale price ₹1,499
₹ /
(Inclusive of all taxes)

Size

The Model's height is 6'2 and he is wearing size XL

  • 7-Days Easy Return & Exchange
  • Free Shipping on Prepaid Orders
  • Get it Fast with Express Delivery
Accessories, perfumes, sunglasses, socks, and innerwear are non-returnable and non-exchangeable due to hygiene reasons

New User
Flat ₹300 OFF On ₹1,999

COPY:

HELLO300

Elevate your casual style with The Bear House Corduroy Bucket Hat. Crafted from high-quality corduroy fabric, this hat offers a luxurious texture and a timeless look. The comfortable and lightweight design ensures all-day wearability, making it perfect for outdoor adventures or adding a stylish touch to your everyday outfits. The Bear House logo is subtly embroidered in red on the front, adding a touch of brand authenticity. Stay cool and protected from the sun while showcasing your fashion-forward sense with this sophisticated corduroy bucket hat.

  • Pattern: Self Design
  • Logo: Bear Metal logo on the front
  • Style: Casual, versatile accessory suitable for various occasions
  • Material: High-quality Corduroy fabric for comfort and durability
  • Care Instructions: Hand wash 

Style#:Kimoc

Shipping Policy

  • A ₹99 handling fee is applicable on all COD orders.
  • Orders are typically dispatched within 1-working day from our warehouse.
  • Tracking details will be shared via WhatsApp and email once the order has been shipped.

Return & Exchange Policy

  • Returns & exchanges accepted within 7 days of delivery.
  • Items must be unused, unworn, and with original tags intact.
  • Sale & promotional orders are exchange-only.
  • Prepaid orders: Refund to original payment method.
  • COD orders: Refund as store credit.
    ₹49 return pickup fee applies.
  • Accessories, perfumes, sunglasses, socks & innerwear are not eligible for return or exchange.
  • Shipping charges are non-refundable

Bear House Clothing Pvt Ltd.,

31/161, near Life Line Hospital, Preethy Nagar, Laggere, Bengaluru, Karnataka 560058



Recently viewed

Shop Men's Mustard Corduroy Bucket Hat Online.
" would otherwise terminate this inline script for every // storefront visitor. '\/' is a valid JS escape for '/', so the runtime value is unchanged. const chatCustomCss = ""; // Add styles for iframe and mobile optimizations const style = document.createElement('style'); style.textContent = ` #embed-iframe { position: fixed; border: none; transition: bottom 0.15s ease-out; } /* Mobile styles (≤768px) */ @media (max-width: 768px) { #embed-iframe { z-index: 1000000000; } #embed-iframe.glance-fab { width: 68px; height: 68px; top: auto; ${fabPlacement === "left" ? 'left: 20px;' : 'right: 20px;'} bottom: var(--bottom-offset, 20px); } #embed-iframe.glance-nudge { width: 255px; height: 180px; ${fabPlacement === "left" ? 'left: 20px;' : 'right: 20px;'} bottom: var(--bottom-offset, 20px); } #embed-iframe.glance-gen-timer { width: 90vw; height: 100px; ${fabPlacement === "left" ? 'left: 20px; right: auto;' : 'right: 20px; left: auto;'} bottom: var(--bottom-offset, 20px); } #embed-iframe.glance-fullscreen { width: 100%; height: 100%; top: 0; left: 0; bottom: 0; right: 0; } body.glance-fullscreen-active { overflow: hidden; position: fixed; width: 100%; height: 100%; } } /* Desktop styles (>768px) */ @media (min-width: 769px) { #embed-iframe { z-index: 1000000000; } #embed-iframe.glance-fab { width: 68px; height: 68px; top: auto; ${fabPlacementDesktop === "left" ? 'left: 6px;' : 'right: 6px;'} bottom: var(--bottom-offset-desktop, 20px); } #embed-iframe.glance-gen-timer { width: 30vw; height: 100px; ${fabPlacementDesktop === "left" ? 'left: 6px; right: auto;' : 'right: 6px; left: auto;'} bottom: var(--bottom-offset-desktop, 20px); } #embed-iframe.glance-nudge { width: 255px; height: 180px; ${fabPlacementDesktop === "left" ? 'left: 6px;' : 'right: 6px;'} bottom: var(--bottom-offset-desktop, 20px); } #embed-iframe.glance-fullscreen { max-width: 450px; width: 100%; border-radius: 24px; margin: 16px; height: calc(100% - 24px); top: 0; bottom: 0; ${fabPlacementDesktop === "left" ? 'left: 0px;' : 'right: 0px;'} box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); } } #timer-iframe { position: fixed; top: -60px; left: 50%; transform: translateX(-50%); width: 320px; max-width: 90vw; height: 60px; z-index: 1000000100; border: none; transition: top 0.6s ease; } #timer-iframe.visible { top: var(--timer-top-offset, 8%); } `; document.head.appendChild(style); // Constants for iframe communication const IFRAME_ORIGIN = 'https://embed.glance.com'; // Glance OAuth constants for iOS login relay const GLANCE_ACCOUNTS_URL = 'https://accounts.glance.com'; const GLANCE_OAUTH_CALLBACK_URI = IFRAME_ORIGIN + '/build/es/latest/oauth-callback.html'; // Google Pay environment: 'TEST' or 'PRODUCTION'. Substituted by switch-env.js // from GPAY_ENV in the active .env file. Default is 'TEST' for safety — // PRODUCTION requires the page origin to match the merchant's registered domain. const GPAY_ENV = 'PRODUCTION'; // Comma-separated UCP payment-handler keys, in preferred order. The first // handler whose config exists in the merchant's /.well-known/ucp.json AND // is usable on this device wins. Substituted by switch-env.js from the active // .env file (PAYMENT_HANDLER_PRIORITY). Set to a card-first order on // merchants where Google Pay isn't reliably configured. const PAYMENT_HANDLER_PRIORITY = 'dev.shopify.card,com.google.pay'; const QUERY_PARAMS = { CHAT: 'g_chat', SCREEN: 'g_screen', COLLECTION_ID: 'g_collection_id', SEARCH_KEY: 'g_search_key' }; // Create iframe element const embedIframe = document.createElement('iframe'); embedIframe.id = 'embed-iframe'; embedIframe.className = 'glance-fab'; // Default to FAB state embedIframe.allow = `camera ${IFRAME_ORIGIN}; web-share ${IFRAME_ORIGIN}; clipboard-write ${IFRAME_ORIGIN};`; // Camera, native share, clipboard document.body.appendChild(embedIframe); // Apply merchant custom CSS inline — beats the media-queried z-index in the // stylesheet above without !important, and survives the glance-* class swaps // (handleSizeUpdateRequest only mutates className). Re-applied after soft // navigation too, whose Object.assign can overwrite the same properties. function applyChatCustomCss() { if (chatCustomCss && chatCustomCss.trim()) { embedIframe.style.cssText += ';' + chatCustomCss; } } applyChatCustomCss(); // Create timer widget iframe (only if gen timer widget is enabled) let timerIframe = null; const timerWidgetType = 'gen_timer'; const timerContainerId = 'timer-iframe'; if (genTimerEnabled) { timerIframe = document.createElement('iframe'); timerIframe.id = timerContainerId; document.body.appendChild(timerIframe); } // Scroll detection variables for timer visibility let lastScrollY = 0; let scrollTimeout = null; let isScrollHidden = false; // Simple throttle utility function function throttle(func, delay) { let timeoutId = null; return function(...args) { if (!timeoutId) { timeoutId = setTimeout(() => { func.apply(this, args); timeoutId = null; }, delay); } }; } // Throttled scroll handler for timer visibility function handleTimerScroll() { const currentScrollY = window.scrollY; const scrollingDown = currentScrollY > lastScrollY; const nearTop = currentScrollY <= 10; // Clear existing timeout if (scrollTimeout) { clearTimeout(scrollTimeout); } // Determine if timer should be hidden due to scroll const shouldHideForScroll = scrollingDown && !nearTop; // Only update if scroll state actually changed if (isScrollHidden !== shouldHideForScroll) { isScrollHidden = shouldHideForScroll; // Apply current timer state with scroll consideration if (timerIframe && currentTimerData) { applyTimerVisibility(currentTimerData); } } lastScrollY = currentScrollY; scrollTimeout = null; } // Create throttled version of scroll handler const throttledTimerScroll = throttle(handleTimerScroll, 100); // 10fps // Store current timer data for scroll-based updates let currentTimerData = null; // Apply timer visibility considering both timer state and scroll state function applyTimerVisibility(data) { if (!timerIframe) return; // Only apply scroll hiding during GENERATING phase // COUNTER phase should always be visible (important completion notification) const shouldApplyScrollHiding = data.phase === 'GENERATING' && isScrollHidden; // Timer should be visible if: // 1. shouldRenderTimer is true AND // 2. NOT animating out from generation logic AND // 3. NOT hidden due to scroll (only during GENERATING phase) const shouldBeVisible = data.shouldRenderTimer && !data.isAnimatingOut && !shouldApplyScrollHiding; if (shouldBeVisible) { timerIframe.classList.add('visible'); } else { timerIframe.classList.remove('visible'); } // Always relay the original state to the timer widget // (scroll state is handled only at the parent level) if (timerIframe.contentWindow) { timerIframe.contentWindow.postMessage({ type: 'TIMER_STATE_SYNC', data: data }, IFRAME_ORIGIN); } } // Cookie management for iframe auth tokens function setCookie(name, value, expiryDays) { const date = new Date(); date.setTime(date.getTime() + expiryDays * 24 * 60 * 60 * 1000); const expires = `expires=${date.toUTCString()}`; document.cookie = `${name}=${value};${expires};path=/;SameSite=Strict;Secure`; } function getCookie(name) { const nameEQ = name + '='; const ca = document.cookie.split(';'); for (let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); } return null; } function deleteCookie(name) { document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; } function getCurrentCookieData() { const cookies = {}; const authTokens = ['anonAccessToken', 'accessToken', 'refreshToken']; authTokens.forEach(tokenName => { const value = getCookie(tokenName); cookies[tokenName] = value; }); return cookies; } const checkoutContext = { // Inline checkout (GPay/Shopify) is disabled on cart-popup stores // (e.g. Shiprocket) — their popup owns checkout. Keep in sync with // CART_POPUP_CHECKOUT_STORE_HANDLES in glance-cart-checkout.js. ready: window.Shopify.shop?.split('.')?.[0] !== 'rijac2021', currency: window.Shopify?.currency?.active || '', country: window.Shopify?.country || '', shopOrigin: window.Shopify?.shop || '' }; (function loadAndInitCartCheckout() { function doInit() { window.GlanceCartCheckout.init({ embedIframe: embedIframe, IFRAME_ORIGIN: IFRAME_ORIGIN, checkoutContext: checkoutContext, GPAY_ENV: GPAY_ENV, PAYMENT_HANDLER_PRIORITY: PAYMENT_HANDLER_PRIORITY }); } // Already loaded (e.g. re-run in this page context) — no need to fetch again. if (window.GlanceCartCheckout && typeof window.GlanceCartCheckout.init === 'function') { doInit(); return; } // Create the element and attach load/error listeners BEFORE setting src/appending, // so the load can never fire before we're listening for it. const scriptEl = document.createElement('script'); scriptEl.async = true; scriptEl.addEventListener('load', function () { if (window.GlanceCartCheckout && typeof window.GlanceCartCheckout.init === 'function') { doInit(); } else { console.error('GlanceAI: GlanceCartCheckout module missing after script load; cart/checkout will be unavailable'); } }); scriptEl.addEventListener('error', function () { console.error('GlanceAI: glance-cart-checkout.js failed to load; cart/checkout will be unavailable'); }); scriptEl.src = "https:\/\/cdn.shopify.com\/extensions\/01a0ee58-5bb1-7779-8488-901f4c604044\/glance-ai-prod-154\/assets\/glance-cart-checkout.js"; document.body.appendChild(scriptEl); })(); /** * Handle navigation request from iframe (iframe has already updated its URL and UI) */ function handleSoftNavigationRequest(data) { const { navigationState, replace, css } = data; // Update iframe CSS based on navigation state if (embedIframe && css) { Object.assign(embedIframe.style, css); // Re-apply merchant custom CSS last so its declarations win over // anything the navigation payload set (later inline declarations win). applyChatCustomCss(); } // Update host URL to match iframe's navigation state updateUrl(navigationState, replace); // No need to notify iframe - it has already updated itself } /** * Handle hard navigation request from iframe to navigate to a specific URL */ function handleHardNavigationRequest(data) { const { url } = data; if (url) { console.log('Navigating to:', url); window.location.href = url; } else { console.warn('Hard navigation request received without URL'); } } /** * Handle back navigation request from iframe */ function handleBackNavigation() { console.log('Handling back navigation'); window.history.back(); } function handleOpenGoogleAuth() { const POPUP_NAME = 'glance-auth-popup'; const POLL_INTERVAL_MS = 200; const SAFETY_TIMEOUT_MS = 5 * 60 * 1000; const state = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : ('oauth-' + Date.now() + '-' + Math.random().toString(36).slice(2)); const authorizeUrl = GLANCE_ACCOUNTS_URL + '/api/v0/oauth2/authorize?' + new URLSearchParams({ response_type: 'code', client_id: 'ai-looks-embed', redirect_uri: GLANCE_OAUTH_CALLBACK_URI, state, provider: 'GOOGLE' }).toString(); const authPopup = window.open(authorizeUrl, POPUP_NAME); if (!authPopup) { console.error('[iOS-OAuth] window.open blocked'); postCancelToIframe(); return; } let popupDone = false; let closedPoller; let safetyTimeout; function cleanup() { clearInterval(closedPoller); clearTimeout(safetyTimeout); window.removeEventListener('message', onOAuthMessage); } function postCancelToIframe() { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'GLANCE_OAUTH_CANCELLED' }, IFRAME_ORIGIN); } } function onOAuthMessage(e) { if (e.source !== authPopup) return; if (!e.data || e.data.type !== 'GLANCE_OAUTH_CODE') return; if (e.data.state !== state) return; popupDone = true; cleanup(); if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage( { type: 'GLANCE_OAUTH_CODE', data: { code: e.data.code, error: e.data.error || null, state: e.data.state, redirectUri: GLANCE_OAUTH_CALLBACK_URI } }, IFRAME_ORIGIN ); } } window.addEventListener('message', onOAuthMessage); closedPoller = setInterval(() => { if (!authPopup.closed) return; cleanup(); if (!popupDone) postCancelToIframe(); }, POLL_INTERVAL_MS); safetyTimeout = setTimeout(() => { cleanup(); if (!popupDone) { try { authPopup.close(); } catch (_e) { /* popup already closed */ } postCancelToIframe(); } }, SAFETY_TIMEOUT_MS); } /** * Update the host URL based on navigation state */ function updateUrl(navigationState, replace = false) { // Construct query string from NavigationState object const params = new URLSearchParams(); if (navigationState.isChatOpen) { params.set(QUERY_PARAMS.CHAT, 'true'); } if (navigationState.currentScreen) { params.set(QUERY_PARAMS.SCREEN, navigationState.currentScreen); } if (navigationState.collectionId) { params.set(QUERY_PARAMS.COLLECTION_ID, navigationState.collectionId); } if (navigationState.searchKey) { params.set(QUERY_PARAMS.SEARCH_KEY, navigationState.searchKey); } const queryString = params.toString(); const newUrl = queryString ? `${window.location.pathname}?${queryString}` : window.location.pathname; // Preserve history state const historyState = history.state || {}; const updatedState = { ...historyState, glance: navigationState }; // Update the host URL without reloading. // Prefer the pre-captured refs (bypass converters installed after // init); fall back to the live history methods if unavailable. const doReplace = (window.glanceNav && window.glanceNav.replaceState) || window.history.replaceState.bind(window.history); const doPush = (window.glanceNav && window.glanceNav.pushState) || window.history.pushState.bind(window.history); if (replace) { doReplace(updatedState, '', newUrl); } else { doPush(updatedState, '', newUrl); } console.log('Host URL updated:', newUrl); } /** * Parse current URL and return navigation state */ function getCurrentNavigationState() { const params = new URLSearchParams(window.location.search); return { isChatOpen: params.get(QUERY_PARAMS.CHAT) === 'true', currentScreen: params.get(QUERY_PARAMS.SCREEN) || null, isPopupOpen: params.get(QUERY_PARAMS.SCREEN) !== null, collectionId: params.get(QUERY_PARAMS.COLLECTION_ID) || undefined, searchKey: params.get(QUERY_PARAMS.SEARCH_KEY) || undefined }; } /** * Notify iframe of URL update via postMessage */ function notifyIframeOfUrlUpdate(navigationState, replace = false) { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'URL_UPDATE', data: { navigationState, replace } }, IFRAME_ORIGIN); } } /** * Open Chat flow iframe of URL update via postMessage */ function openChat(data) { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'OPEN_CHAT', data: data || {} }, IFRAME_ORIGIN); } } /** * Open Chat with Image via postMessage */ function openChatWithImage(data) { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'OPEN_IMAGE_SEARCH', data: data || {} }, IFRAME_ORIGIN); } } /** * Try On flow iframe with data via postMessage */ function tryOn(data) { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'OPEN_TRYON', data }, IFRAME_ORIGIN); } } /** * Open Your Looks flow via postMessage */ function openYourLooks() { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'OPEN_YOUR_LOOKS' }, IFRAME_ORIGIN); } } /** * Handle widget analytics flow iframe with data via postMessage */ function handleWidgetAnalytics(data) { if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'WIDGET_ANALYTICS', data, }, IFRAME_ORIGIN); } } /** * Initialize iframe with current parent URL state * Initialize iframe with clean URL (no query params) */ function initializeIframe() { if (!embedIframe) return; // Always use clean base URL without any query parameters // Navigation state will be sent via postMessage after initialization const baseIframeUrl = `${IFRAME_ORIGIN}/build/es/latest/iframe.html`; // Set iframe src with clean URL embedIframe.src = baseIframeUrl; // Conditionally initialize timer iframe if enabled if (genTimerEnabled && timerIframe) { const widgetUrl = `${IFRAME_ORIGIN}/build/es/latest/widgets/widget.html?widgetType=${timerWidgetType}&containerId=${timerContainerId}`; timerIframe.src = widgetUrl; } } // Page type and identifier functions function getPageType() { return 'PDP'; } function getPageIdentifier() { return String(46142192845051); } /** * Send initialization data to iframe including cookie data and current navigation state * @param {Window} targetWindow - The iframe's contentWindow to send data to (defaults to embedIframe) */ function sendInitializationData(targetWindow) { // Default to embedIframe if no targetWindow provided const target = targetWindow || (embedIframe && embedIframe.contentWindow); if (target) { const cookieData = getCurrentCookieData(); // Get pixel ID from localStorage let pixelId = ''; let shouldListenForPixelId = false; try { const iDspCookie = localStorage.getItem('iDSP_Cookie'); if (iDspCookie) { const extractedId = iDspCookie.split('*')[0]; if (extractedId) { pixelId = extractedId; console.log('======Pixel ID from localStorage iDSP_Cookie:', pixelId); } else { shouldListenForPixelId = true; console.log('======Pixel ID not found in localStorage iDSP_Cookie, will start polling'); } } else { // Cookie not found - we should listen for it shouldListenForPixelId = true; console.log('======iDSP_Cookie not found, will start polling'); } } catch (e) { console.warn('Failed to retrieve pixelId from localStorage:', e); pixelId = ''; shouldListenForPixelId = true; } // Determine if chat nudge should be shown on current page let showChatNudge = false; showChatNudge = true; const initData = { partnerId: "e7c2e013-aea8-450b-af5a-d9c2558e2de8", catalogId: "bearhouseindia", region: null, theme: "purple", cornerStyle: "rounded", fontStyle: "montserrat", chatFontStyle: "montserrat", storeHandle: window.Shopify.shop?.split('.')?.[0] || '', bottomOffset: (isDesktop ? bottomOffsetDesktop : bottomOffset) + 'px', fabPlacement: isDesktop ? fabPlacementDesktop : fabPlacement, brandLogo: "https:\/\/thebearhouse.com\/cdn\/shop\/files\/Frame_78_616c6580-bd5c-4281-8b26-8b0107aa9953.webp?v=1772082159\u0026width=200", pageUrl: window.location.href, pageType: getPageType(), pageIdentifier: getPageIdentifier(), productId: "8676986749179", productData: { "merchantVariantId": "46142192845051", "productName": "Kimoc", "productImageUrl": "\/\/thebearhouse.com\/cdn\/shop\/files\/1_d5691036-18c3-400c-984d-0dad1d85e865.jpg?v=1757341390\u0026width=800", "productImages": ["\/\/thebearhouse.com\/cdn\/shop\/files\/1_d5691036-18c3-400c-984d-0dad1d85e865.jpg?v=1757341390\u0026width=800","\/\/thebearhouse.com\/cdn\/shop\/files\/2_4d72dcb5-0037-4b6b-a8dc-71ae155e3903.jpg?v=1757341391\u0026width=800","\/\/thebearhouse.com\/cdn\/shop\/files\/3_eea8c39c-0305-40c0-95be-d2347628ac32.jpg?v=1757341391\u0026width=800"], "deeplinkUrl": "https:\/\/thebearhouse.com\/products\/kimoc", "price": { "currency": "₹", "price": 1499.0,"discountPrice": 1199.0, "discount": 20 }, "sizes": [{"id": "46142192845051","value": "OneSize","inStock": true}] }, cookieData, pixelId, pageTitle: document.title, referrer: document.referrer, showChatNudge: showChatNudge, isDesktop: desktopEnabled && isDesktop, genTimerEnabled: genTimerEnabled, checkout: checkoutContext }; // Only send navigation state and setup pixel polling for embedIframe const isEmbedIframe = target === embedIframe?.contentWindow; if (isEmbedIframe) { // Send initialization data target.postMessage({ type: 'INIT_DATA_RESPONSE', data: initData }, IFRAME_ORIGIN); // Scrape parent DOM for enrichment (coupons/offers) — PDP only, // since the embed iframe cannot access the parent document itself. if (getPageType() === 'PDP') { try { const rawText = (document.body.innerText || '') .replace(/\s+/g, ' ').trim().slice(0, 50000); const rawSchemaJson = Array.from( document.querySelectorAll('script[type="application/ld+json"]') ).map(tag => tag.textContent || '').filter(Boolean).join('\n').slice(0, 8000); target.postMessage({ type: 'PAGE_CONTEXT_DATA', data: { rawText, rawSchemaJson } }, IFRAME_ORIGIN); } catch (e) { console.warn('GlanceAI: PAGE_CONTEXT_DATA scrape failed', e); } } // Also send current navigation state from parent URL const navigationState = getCurrentNavigationState(); notifyIframeOfUrlUpdate(navigationState, true); // Use replace=true for initial state // If pixelId was not found, set up polling for when external script sets it if (shouldListenForPixelId) { setupPixelIdListener(); } } //update genTimer initData const isTimerIframe = target === timerIframe?.contentWindow; if(isTimerIframe && genTimerEnabled) { const wInitData = {...initData}; wInitData.widgetData = { widgetType: timerWidgetType, containerId: timerContainerId } // Send initialization data timerIframe.contentWindow.postMessage({ type: 'INIT_WIDGET_DATA_RESPONSE', data: wInitData }, IFRAME_ORIGIN); } } } // Polling configuration for pixelId const PIXEL_ID_POLLING_INTERVAL = 1000; // Check every 1 second const PIXEL_ID_POLLING_MAX_ATTEMPTS = 30; // Max 30 attempts (30 seconds) /** * Notify iframe of pixelId update via postMessage */ function notifyIframeOfPixelIdUpdate(pixelId) { if (embedIframe && embedIframe.contentWindow && pixelId) { embedIframe.contentWindow.postMessage({ type: 'PIXEL_ID_UPDATE', data: { pixelId } }, IFRAME_ORIGIN); console.log('Sent PIXEL_ID_UPDATE to iframe:', pixelId); } } /** * Set up a listener (polling) for the pixelId in localStorage */ function setupPixelIdListener() { let attempts = 0; const intervalId = setInterval(() => { attempts++; if (attempts > PIXEL_ID_POLLING_MAX_ATTEMPTS) { console.warn('Max attempts reached for pixelId polling. Pixel ID not found.'); clearInterval(intervalId); return; } try { const iDspCookie = localStorage.getItem('iDSP_Cookie'); if (iDspCookie) { const extractedId = iDspCookie.split('*')[0]; if (extractedId) { console.log('======Pixel ID found via polling:', extractedId); notifyIframeOfPixelIdUpdate(extractedId); clearInterval(intervalId); } } } catch (e) { console.warn('Error during pixelId polling:', e); } }, PIXEL_ID_POLLING_INTERVAL); console.log('Started polling for pixelId...'); } /** * Handle iframe size update request */ function handleSizeUpdateRequest(data) { const { widgetType } = data; console.log('Host received SIZE_UPDATE_REQUEST:', widgetType); // Remove existing glance classes and apply new one if (embedIframe) { embedIframe.className = embedIframe.className .split(' ') .filter(cls => !cls.startsWith('glance-')) .join(' ') + ` glance-${widgetType}`; } // Handle body scroll based on iframe state if (widgetType === 'fullscreen') { // Disable body scrolling when going fullscreen document.body.classList.add('glance-fullscreen-active'); } else { // Re-enable body scrolling when leaving fullscreen (fab or nudge) document.body.classList.remove('glance-fullscreen-active'); } } // Add event listeners // Listener for receiving messages from iframe window.addEventListener('message', (event) => { // Security check: ensure message is from expected origin if (event.origin !== IFRAME_ORIGIN) return; const { type, data } = event.data; switch (type) { case 'REQUEST_INIT_DATA': console.log('Host received REQUEST_INIT_DATA:'); sendInitializationData(event.source); break; case 'REQUEST_WIDGET_INIT_DATA': if(data.widgetType !== timerWidgetType || data.containerId !== timerContainerId) { break; } sendInitializationData(event.source); break; case 'IFRAME_READY': console.log('Host received IFRAME_READY signal'); window.GlanceIframeReady = true; // If widget manager is already loaded, notify it if (window.GlanceWidgetManager && typeof window.GlanceWidgetManager.setIframeReady === 'function') { window.GlanceWidgetManager.setIframeReady(); } break; case 'SOFT_NAVIGATE_REQUEST': console.log('Host received SOFT_NAVIGATE_REQUEST:', data); handleSoftNavigationRequest(data); break; case 'HARD_NAVIGATE_REQUEST': console.log('Host received HARD_NAVIGATE_REQUEST:', data); handleHardNavigationRequest(data); break; case 'NAVIGATE_BACK_REQUEST': console.log('Host received NAVIGATE_BACK_REQUEST'); handleBackNavigation(); break; case 'OPEN_GOOGLE_AUTH': handleOpenGoogleAuth(); break; case 'SIZE_UPDATE_REQUEST': handleSizeUpdateRequest(data); break; case 'COOKIE_SET_REQUEST': console.log('Host received COOKIE_SET_REQUEST:', data); const { name, value, expiryDays } = data; setCookie(name, value, expiryDays); break; case 'COOKIE_DELETE_REQUEST': console.log('Host received COOKIE_DELETE_REQUEST:', data); deleteCookie(data.name); break; case 'OPEN_CHAT': openChat(data); break; case 'OPEN_IMAGE_SEARCH': console.log('Request to Open Chat with Image', data); openChatWithImage(data); break; case 'OPEN_TRYON': console.log('Request to Try On with data:', data); tryOn(data); break; case 'OPEN_YOUR_LOOKS': console.log('Request to open Your Looks'); openYourLooks(); break; case 'WIDGET_ANALYTICS': console.log('Request to handle widget analytics with data:', data); handleWidgetAnalytics(data); break; case 'TIMER_STATE_UPDATE': // Only handle timer state updates if gen timer widget is enabled if (genTimerEnabled) { console.log('Host received TIMER_STATE_UPDATE:', data); // Store current timer data for scroll-based updates currentTimerData = data; // Apply timer visibility with scroll consideration applyTimerVisibility(data); // Manage scroll listener based on timer state if (data.shouldRenderTimer) { // Add scroll listener when timer should be active window.addEventListener('scroll', throttledTimerScroll, { passive: true }); } else { // Remove scroll listener when timer is not active window.removeEventListener('scroll', throttledTimerScroll, { passive: true }); // Reset scroll state isScrollHidden = false; lastScrollY = 0; if (scrollTimeout) { clearTimeout(scrollTimeout); scrollTimeout = null; } } } break; case 'REQUEST_TIMER_STATE': // Only handle timer state requests if gen timer widget is enabled if (genTimerEnabled) { console.log('Host received REQUEST_TIMER_STATE, relaying to embed-iframe'); if (embedIframe && embedIframe.contentWindow) { embedIframe.contentWindow.postMessage({ type: 'REQUEST_TIMER_STATE' }, IFRAME_ORIGIN); } } break; case 'CART_GET_REQUEST': console.log('Host received CART_GET_REQUEST'); if (window.GlanceCartCheckout) window.GlanceCartCheckout.handleCartGetRequest(); break; case 'CART_ADD_REQUEST': console.log('Host received CART_ADD_REQUEST:', data); if (window.GlanceCartCheckout) window.GlanceCartCheckout.handleCartAddRequest(data); break; case 'CART_UPDATE_REQUEST': console.log('Host received CART_UPDATE_REQUEST:', data); if (window.GlanceCartCheckout) window.GlanceCartCheckout.handleCartUpdateRequest(data); break; case 'OPEN_CART': console.log('Host received OPEN_CART'); if (window.GlanceCartCheckout) window.GlanceCartCheckout.handleOpenCart(); break; case 'OPEN_CHECKOUT': console.log('Host received OPEN_CHECKOUT'); if (window.GlanceCartCheckout) window.GlanceCartCheckout.handleCheckoutRedirect(); break; case 'CHECKOUT_BEGIN_REQUEST': console.log('Host received CHECKOUT_BEGIN_REQUEST:', data); if (window.GlanceCartCheckout) window.GlanceCartCheckout.handleCheckoutBegin(data); break; case 'CHECKOUT_COMPLETE_RESPONSE': { if (window.GlanceCartCheckout) window.GlanceCartCheckout.resolveCheckoutComplete(data); break; } default: console.log('Host received unknown message type:', type); break; } }); // Listener for popstate (browser back/forward buttons) window.addEventListener('popstate', (event) => { console.log('Host popstate event:', window.location.href); // Get current navigation state from URL const navigationState = getCurrentNavigationState(); // Notify iframe to update its URL without reloading notifyIframeOfUrlUpdate(navigationState, true); // Use replace=true for back/forward }); // Initialize iframe with current navigation state initializeIframe(); // Widget configuration based on page type and settings if (!isAllowedPage) { console.log('Widgets enabled but GlanceAI not allowed on this page'); return; } console.log('Native widgets enabled and page allowed, checking widget configuration...'); // Determine which widgets are enabled for current page const enabledWidgets = {}; // Widget-specific rollout checks const widgetRollouts = { try_on_button: 100, try_on_banner: 100, search: 100 }; // Check rollout for each widget using session storage const isInRollout = (widgetType) => { const rolloutKey = `glance_widget_rollout_${widgetType}`; // Check if already determined in this session const storedValue = sessionStorage.getItem(rolloutKey); if (storedValue !== null) { return storedValue === 'true'; } // Calculate and store for this session const rolloutPercentage = widgetRollouts[widgetType] || 100; const isIncluded = Math.random() * 100 < rolloutPercentage; sessionStorage.setItem(rolloutKey, isIncluded.toString()); return isIncluded; }; enabledWidgets.try_on_button = true && true && isInRollout('try_on_button'); enabledWidgets.try_on_banner = false && false && isInRollout('try_on_banner'); enabledWidgets.search = false && false && isInRollout('search'); // Generic gating for Svelte custom-element widgets. The list is // auto-generated by the embed build (window.GLANCE_SVELTE_WIDGETS), so // adding a widget directory + rebuilding wires it up here automatically — // no per-widget edits in this file. const svelteWidgets = window.GLANCE_SVELTE_WIDGETS || []; const currentPageType = getPageType(); svelteWidgets.forEach(w => { const pageAllowed = currentPageType === 'PDP' ? w.productPage : currentPageType === 'PLP' ? w.collectionPage : currentPageType === 'HOME' ? w.homePage : false; // Expose this widget's rollout % so the shared isInRollout() can use it. widgetRollouts[w.key] = w.rollout ?? 100; // && short-circuits exactly like the iframe widgets above: isInRollout // (which reads/writes sessionStorage) only runs when enabled + page-allowed. enabledWidgets[w.key] = w.enabled && pageAllowed && isInRollout(w.key); }); // Check if any widget is enabled for this page const hasEnabledWidgets = Object.values(enabledWidgets).some(enabled => enabled); // Svelte widgets need the runtime + config bundles loaded. const enabledSvelteWidgets = svelteWidgets.filter(w => enabledWidgets[w.key]); const hasSvelteWidgets = enabledSvelteWidgets.length > 0; if (hasEnabledWidgets) { // Pass configuration to widget manager window.GlanceWidgetConfig = enabledWidgets; // Expose theme values for Svelte widgets window.GLANCE_WIDGET_THEME = "purple"; window.GLANCE_WIDGET_CORNER_STYLE = "rounded"; window.GLANCE_WIDGET_FONT = "montserrat"; // Pass isDesktop flag globally window.GlanceIsDesktop = isDesktop; // Track iframe ready state globally window.GlanceIframeReady = false; // Load widget infrastructure // First, set the IFRAME_ORIGIN for widgets to use window.GLANCE_IFRAME_ORIGIN = IFRAME_ORIGIN; // Set up asset URLs for widgets to use window.GLANCE_WIDGET_ASSETS = { glanceGradientLogo: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/glance-gradient-logo.svg', yourPhoto: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/your-photo.png', blackShirt: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/black-shirt.png', blackShirtModel: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/black-shirt-model.png', blueShirt: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/blue-shirt.png', blueShirtModel: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/blue-shirt-model.png', greenShirt: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/green-shirt.png', greenShirtModel: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/green-shirt-model.png', redShirt: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/red-shirt.png', redShirtModel: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/red-shirt-model.png', tryOnConvertArrow: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/try-on-convert-arrow.svg', tryOnWhiteStar: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/try-on-white-star.svg', glanceAiLogo: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/glance-ai.svg', chatWidgetImg: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/chat-widget-img.png', blackStar: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/black-star.svg', starIconWhite: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/star-icon-white.svg', mixMatchVector: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/mix-match-vector.svg' }; // Define widget configurations with their asset URLs const widgetAssets = []; widgetAssets.push({ key: 'try_on_button', url: 'https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/widget-try-on-button.js', name: 'Try On Button' }); // Register every auto-generated Svelte widget enabled for this page. Their // asset URLs come from the build-generated GLANCE_SVELTE_WIDGETS list, so no // per-widget entry is needed here. enabledSvelteWidgets.forEach(w => { widgetAssets.push({ key: w.key, url: w.url, name: w.key, isModule: true }); }); // Helper to load a script const loadScript = (src, name, isModule = false) => { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = src; if (isModule) { script.type = 'module'; } script.onload = () => resolve(); script.onerror = () => { console.error(`Failed to load ${name}`); reject(); }; document.head.appendChild(script); }); }; // Load core first, then config, then runtime for Svelte widgets if needed, then widgets, then initialize loadScript('https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/glance-widgets-core.js', 'Core widget infrastructure') .then(() => { if (hasSvelteWidgets) { return loadScript('https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/glance-widgets-config.js', 'Svelte widget configs'); } return Promise.resolve(); }) .then(() => { if (hasSvelteWidgets) { return loadScript('https://cdn.shopify.com/extensions/01a0ee58-5bb1-7779-8488-901f4c604044/glance-ai-prod-154/assets/build-svelte-runtime.js', 'Svelte runtime', true); } return Promise.resolve(); }) .then(() => { // Load all enabled widget components const promises = []; widgetAssets.forEach(widget => { if (enabledWidgets[widget.key]) { promises.push(loadScript(widget.url, widget.name, widget.isModule ?? false)); } }); return Promise.all(promises); }) .then(() => { if (hasSvelteWidgets) { const timeout = new Promise(resolve => setTimeout(resolve, 2000)); const defined = Promise.all( enabledSvelteWidgets.map(w => customElements.whenDefined(w.tag)) ); return Promise.race([defined, timeout]); } }) .then(() => { if (window.GlanceWidgetManager) { window.GlanceWidgetManager.init(); } }) .catch(error => { console.error('Error loading widget system:', error); }); } // Auto-detect and track sticky bar (.yt-sticky-bar-container) for dynamic FAB positioning (PDP only) (function setupBottomOffsetTracking() { // Only run on product pages for specific store const storeHandle = window.Shopify.shop?.split('.')?.[0] || ''; if (getPageType() !== 'PDP' || storeHandle !== 'thebearhouseindia') return; // Use mobile bottom offset as base (sticky bar tracking is for mobile) const baseBottom = bottomOffset; const iframeElem = document.getElementById('embed-iframe'); // Helper function to extract translateY from transform matrix function getTranslateY(element) { const transform = window.getComputedStyle(element).transform; if (transform === 'none') return 0; const matrix = transform.match(/matrix.*\((.+)\)/); if (matrix) { const values = matrix[1].split(', '); return parseFloat(values[5]) || 0; } return 0; } // Helper function to calculate and set iframe height based on sticky bar function updateIframeHeightForStickyBar() { const stickyBar = document.querySelector('#yt001-widget-reward .yt-sticky-bar-container'); if (stickyBar) { const translateY = getTranslateY(stickyBar); const stickyBarHeight = stickyBar.offsetHeight; const visibleAmount = Math.max(0, stickyBarHeight - translateY); const newBottom = baseBottom + visibleAmount - 75; iframeElem.style.height = `calc(100% - 24px - ${newBottom}px)`; } } // Watch for class changes on iframe (desktop only) if (isDesktop && iframeElem) { const classObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'attributes' && mutation.attributeName === 'class') { if (iframeElem.classList.contains('glance-fullscreen')) { // Fullscreen added - adjust height based on sticky bar position updateIframeHeightForStickyBar(); } else { // Fullscreen removed - reset height iframeElem.style.height = null; } } }); }); classObserver.observe(iframeElem, { attributes: true }); } // Function to set up requestAnimationFrame tracking for sticky bar transform function startStickyBarTracking(stickyBar) { console.log('GlanceAI Embed: Sticky bar detected, enabling dynamic FAB positioning with rAF'); let lastTranslateY = null; function trackStickyBar() { const translateY = getTranslateY(stickyBar); // Only update if translateY changed if (translateY !== lastTranslateY) { lastTranslateY = translateY; const stickyBarHeight = stickyBar.offsetHeight; // translateY = 0 means fully visible, translateY = height means fully hidden const visibleAmount = Math.max(0, stickyBarHeight - translateY); const newBottom = baseBottom + visibleAmount - 45; // 45px margin document.documentElement.style.setProperty('--bottom-offset', newBottom + 'px'); document.documentElement.style.setProperty('--bottom-offset-desktop', newBottom + 'px'); // Adjust fullscreen iframe height (desktop only) if (isDesktop && iframeElem.classList.contains('glance-fullscreen')) { iframeElem.style.height = `calc(100% - ${newBottom}px)`; } } requestAnimationFrame(trackStickyBar); } // Start tracking requestAnimationFrame(trackStickyBar); console.log('GlanceAI Embed: Started tracking sticky bar with requestAnimationFrame'); } // Check if sticky bar already exists in DOM const existingStickyBar = document.querySelector('#yt001-widget-reward .yt-sticky-bar-container'); if (existingStickyBar) { startStickyBarTracking(existingStickyBar); return; } // Sticky bar not found - set up MutationObserver to watch for it console.log('GlanceAI Embed: Sticky bar not found yet, watching for DOM changes...'); const mutationObserver = new MutationObserver((mutations) => { // Check if sticky bar has been added to DOM const stickyBar = document.querySelector('#yt001-widget-reward .yt-sticky-bar-container'); if (stickyBar) { // Found it! Start tracking and disconnect mutation observer mutationObserver.disconnect(); startStickyBarTracking(stickyBar); } }); // Watch entire document for child additions (subtree includes all descendants) mutationObserver.observe(document.body, { childList: true, subtree: true }); })(); } } catch (error) { console.error('GlanceAI Embed: Unexpected error during initialization:', error); }
Get the app now Enjoy exclusive offers on app
DOWNLOAD APP
Get our app now!
Scan the QR code below!