{"id":39741,"date":"2025-04-21T09:00:00","date_gmt":"2025-04-21T07:00:00","guid":{"rendered":"https:\/\/www.everyday-guide.com\/site\/stop-overpaying-at-rack-room-shoes-8-things-every-shopper-should-know\/"},"modified":"2026-02-07T07:48:49","modified_gmt":"2026-02-07T06:48:49","slug":"stop-overpaying-at-rack-room-shoes-8-things-every-shopper-should-know","status":"publish","type":"post","link":"https:\/\/www.everyday-guide.com\/site\/stop-overpaying-at-rack-room-shoes-8-things-every-shopper-should-know\/","title":{"rendered":"Stop Overpaying at Rack Room Shoes: 8 Things Every Shopper Should Know"},"content":{"rendered":"\n<ul class=\"wp-block-list\">\n<li><strong>Rack Room's BOGO deals run almost year-round, but timing your purchase around key sales events can stack your savings even further.<\/strong><\/li>\n<li><strong>Their rewards program, app-only coupons, and clearance section are easy money-savers that most shoppers completely ignore.<\/strong><\/li>\n<li><strong>Back-to-school season is the single best time to buy, but only if you shop early and know the tricks.<\/strong><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1080\" height=\"720\" src=\"https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img2_v2.jpg\" alt=\"Brand image\" class=\"wp-image-40208\" srcset=\"https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img2_v2.jpg 1080w, https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img2_v2-300x200.jpg 300w, https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img2_v2-1024x683.jpg 1024w, https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img2_v2-768x512.jpg 768w\" sizes=\"auto, (max-width: 1080px) 100vw, 1080px\" \/><\/figure>\n\n\n\n\n<h2 class=\"wp-block-heading\">1. Sign Up for Rewards Before You Buy Anything<\/h2>\n\n\n\n<p>This is the easiest move you can make, and too many people skip it. Rack Room Rewards is free. It takes 30 seconds to sign up in store or on the app. And it pays off immediately.<\/p><div id=\"relatedsearches1\" class=\"every-content-2\" style=\"height: 450px;\"><script>console.log(\"RSOC loading..\");<\/script>\r\n<!-- Initialize Google CSA object - Required for ad functionality -->\r\n<script type=\"text\/javascript\" charset=\"utf-8\">\r\n\t(function(g,o){g[o]=g[o]||function(){(g[o]['q']=g[o]['q']||[]).push(\r\n\t\targuments)},g[o]['t']=1*new Date})(window,'_googCsa');\r\n<\/script><\/div><style>\r\n  #relatedsearches1,\r\n  #relatedsearches2 {\r\n    \/* Base container styles - final appearance *\/\r\n    margin-bottom: 20px;\r\n    padding: 15px;\r\n    background-color: #111827; \/* Final background color (gray-900) *\/\r\n    border-radius: 8px;\r\n    min-height: 250px; \/* Restore a reasonable min-height *\/\r\n    box-sizing: border-box;\r\n    overflow: hidden;\r\n    position: relative; \/* Needed to contain the absolute overlay *\/\r\n  }\r\n\r\n  \/* REMOVED .skeleton-active styles *\/\r\n\r\n  .skeleton-overlay {\r\n    position: absolute;\r\n    inset: 0; \/* Cover parent *\/\r\n    z-index: 10; \/* Ensure it's on top *\/\r\n    pointer-events: none; \/* Prevent interaction *\/\r\n    border-radius: 8px; \/* Match parent *\/\r\n\r\n    \/* --- Skeleton visuals applied directly to the overlay --- *\/\r\n    --skeleton-bar-height: 35px;\r\n    --skeleton-gap-height: 15px;\r\n    --skeleton-unit-height: calc(var(--skeleton-bar-height) + var(--skeleton-gap-height));\r\n    --skeleton-padding: 15px;\r\n    --skeleton-bar-color: #374151; \/* gray-700 *\/\r\n    --skeleton-bg-color: #1f2937;  \/* gray-800 *\/\r\n    --skeleton-shimmer-color: rgba(52, 211, 153, 0.1); \/* emerald-400 10% *\/\r\n\r\n    background-color: var(--skeleton-bg-color);\r\n    background-image:\r\n      linear-gradient(to right, transparent, var(--skeleton-shimmer-color), transparent),\r\n      linear-gradient(var(--skeleton-bar-color) var(--skeleton-bar-height), transparent 0);\r\n    background-size:\r\n      200% var(--skeleton-bar-height),\r\n      calc(100% - (2 * var(--skeleton-padding))) var(--skeleton-unit-height);\r\n    background-repeat: repeat-y;\r\n    background-position:\r\n      calc(-200% + var(--skeleton-padding)) var(--skeleton-padding),\r\n      var(--skeleton-padding) var(--skeleton-padding);\r\n    animation: shimmer 1.5s infinite linear;\r\n    \/* --- End Skeleton Visuals --- *\/\r\n\r\n    \/* --- Visibility Control --- *\/\r\n    opacity: 0;\r\n    transition: opacity 0.3s ease-out;\r\n  }\r\n\r\n  .skeleton-overlay.skeleton-visible {\r\n    opacity: 1;\r\n  }\r\n\r\n  @keyframes shimmer {\r\n    to {\r\n       background-position:\r\n        calc(200% + var(--skeleton-padding)) var(--skeleton-padding),\r\n        var(--skeleton-padding) var(--skeleton-padding);\r\n    }\r\n  }\r\n\r\n  \/* No longer need rules for .skeleton-loading class or :empty *\/\r\n\r\n<\/style>\n\n\n\n<p>Here's what you get:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>$15 reward for every $200 spent<\/strong> (that's a 7.5% return)<\/li>\n<li><strong>$10 birthday reward<\/strong> during your birthday month<\/li>\n<li><strong>60-day return window<\/strong> instead of the standard 30 days<\/li>\n<li><strong>Early access to promotions<\/strong> and members-only coupon codes<\/li>\n<\/ul>\n\n\n\n<p>The extended return window alone justifies signing up. Shoes that feel great in the store can start pinching after a full day of wear. Having 60 days instead of 30 gives you enough time to actually test them. Just remember to keep the tags on until you're sure.<\/p>\n\n\n\n<p>Pro tip: sign up with your actual birthday. The $10 reward is essentially free money. Set a calendar reminder to use it before it expires.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Understand How BOGO Actually Works (Most People Get This Wrong)<\/h2>\n\n\n\n<p>Rack Room's BOGO deals are their signature promotion, but there are different versions and they don't all work the same way.<\/p>\n\n\n\n<p><strong>BOGO Half Off<\/strong> is the standard deal that runs most of the year. Buy one pair at full price, get 50% off the second pair. The discount always applies to the cheaper pair. So if you're buying a $90 pair and a $60 pair, you'll pay $90 + $30 = $120 total.<\/p>\n\n\n\n<p><strong>BOGO Free<\/strong> is the big one. It shows up during major sales events: back-to-school, Black Friday, and occasionally during spring clearance. Buy one pair, get the second free. Same rule applies. The free pair is always the lower-priced one.<\/p>\n\n\n\n<p>Here's the trick most shoppers miss: <strong>you can mix and match across categories.<\/strong> Men's plus kids'. Women's plus men's. Athletic plus casual. There's no restriction on combining different sections. So if you need <a href=\"https:\/\/www.everyday-guide.com\/site\/aoym\" title=\"Holabird Sports\" class=\"pretty-link-keyword\"rel=\"nofollow sponsored \" target=\"_blank\">running shoes<\/a> for yourself and sneakers for your kid, both count toward the deal.<\/p>\n\n\n\n<p>And here's what not to do: don't buy a second pair you don't need just because the deal exists. A $60 pair at 50% off is still $30 you're spending. If you only need one pair of shoes, BOGO isn't saving you anything. It's costing you more.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1080\" height=\"720\" src=\"https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img3_v2.jpg\" alt=\"Brand image\" class=\"wp-image-40209\" srcset=\"https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img3_v2.jpg 1080w, https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img3_v2-300x200.jpg 300w, https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img3_v2-1024x683.jpg 1024w, https:\/\/www.everyday-guide.com\/site\/wp-content\/uploads\/2026\/02\/rack-room-shoes_article-2-tips_img3_v2-768x512.jpg 768w\" sizes=\"auto, (max-width: 1080px) 100vw, 1080px\" \/><\/figure>\n\n\n\n\n<h2 class=\"wp-block-heading\">3. Download the App for Exclusive Coupons<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/www.everyday-guide.com\/site\/v73k\" title=\"Rack Room Shoes\" class=\"pretty-link-keyword\"rel=\"nofollow sponsored \" target=\"_blank\">Rack Room Shoes<\/a> app is free and gives you access to deals you won't find anywhere else. App-only coupons pop up regularly, usually $10 off $50 or $15 off $75. These sometimes stack with BOGO deals, though not always. Check the fine print on each coupon.<\/p>\n\n\n\n<p>The app also shows you:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your rewards balance and when rewards expire<\/li>\n<li>Current promotions with scannable barcodes for in-store use<\/li>\n<li>Store inventory at your nearest location (not always 100% accurate, but helpful)<\/li>\n<li>Digital receipts if you scan your rewards at checkout<\/li>\n<\/ul>\n\n\n\n<p>One thing the app does well is push notifications for flash sales. These usually last 2-3 days and offer better-than-normal discounts. If you don't want constant notifications, turn them on just during the weeks you're planning to shop, then turn them back off.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Time Your Purchases Around These Key Dates<\/h2>\n\n\n\n<p>Not all shopping days at Rack Room are created equal. Here's when you'll get the best deals:<\/p>\n\n\n\n<p><strong>Back-to-School (late July through mid-August):<\/strong> This is the single best time to shop at Rack Room. BOGO Free deals are most common during this window, and the stores stock up heavily on kids' and athletic shoes. If you're buying for a family, this is your window. Shop the first week of the event for the best size and style selection. By mid-August, popular sizes are picked over.<\/p><div id=\"every-578230752\" class=\"every-content-4\"><div class='content_4' style='min-width: 300px; min-height: 250px;'>\r\n  <\/div><\/div>\n\n\n\n<p><strong>Black Friday \/ Cyber Monday:<\/strong> Another peak for BOGO Free deals, plus additional doorbusters. Online deals tend to mirror in-store offers. Don't fight the crowds. Shop online or go early on Friday morning.<\/p>\n\n\n\n<p><strong>Spring Clearance (March-April):<\/strong> Winter boots and cold-weather shoes get marked down 30-50%. If you plan ahead for next year, this is when to buy boots.<\/p>\n\n\n\n<p><strong>Tax-Free Weekends (varies by state):<\/strong> Many Southern states offer tax-free weekends in late summer for back-to-school shopping. Rack Room participates in all of them. Combine tax-free savings with BOGO and a coupon, and you're stacking three discounts at once.<\/p>\n\n\n\n<p><strong>Worst time to buy:<\/strong> September through October. Back-to-school is over, holiday sales haven't started, and the best BOGO deals are usually paused or reduced to half off only.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Don't Sleep on the Clearance Section<\/h2>\n\n\n\n<p>Every Rack Room has a clearance area, usually in the back of the store or along a side wall. Most shoppers walk right past it. That's a mistake.<\/p>\n\n\n\n<p>Clearance markdowns at Rack Room typically run 30-50% off the original price. And here's the key detail: <strong>clearance shoes often qualify for BOGO deals too.<\/strong> So you can buy a clearance pair at $40 (marked down from $70) and use it as your BOGO pair. That's where the math gets really attractive.<\/p>\n\n\n\n<p>Clearance selection rotates frequently. Last season's colors and discontinued styles hit the clearance rack first. If you don't care about having the newest colorway, you can find solid shoes from Nike, Adidas, and <a href=\"https:\/\/www.everyday-guide.com\/site\/yrcf\" title=\"Skechers\" class=\"pretty-link-keyword\"rel=\"nofollow sponsored \" target=\"_blank\">Skechers<\/a> at 40%+ off. Check back every couple of weeks because new markdowns happen regularly.<\/p>\n\n\n\n<p>One more thing: clearance items online are sometimes different from what's in your local store. Check both. The website occasionally has better clearance pricing on styles that didn't sell well nationally.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Use the &#8220;Ship to Store&#8221; Trick for Free Shipping<\/h2>\n\n\n\n<p>Rack Room's free shipping threshold is $65. If your order is $60, you're either paying $6-$8 for shipping or throwing an extra item in your cart to hit the minimum. Neither option is great.<\/p>\n\n\n\n<p>Instead, use ship to store. It's always free with no minimum purchase. You order online, select your nearest store for pickup, and it arrives within about a week. You can try the shoes on in the store and return them immediately if they don't fit. No shipping costs, no return shipping hassle.<\/p>\n\n\n\n<p>This is also useful for locking in online prices or styles that might not be in your local store. If you spot something on the website that your store doesn't carry, ship to store gets it there without the shipping fee.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Master the Back-to-School Strategy<\/h2>\n\n\n\n<p>If you're a parent, back-to-school shoe shopping at Rack Room deserves its own game plan. Here's how to maximize your savings:<\/p>\n\n\n\n<p><strong>Shop the first week of the back-to-school event.<\/strong> Stores are fully stocked, all sizes are available, and the BOGO Free deal is in full swing. By week three, popular kids' sizes (especially boys' 4-6 and girls' 3-5) start running low.<\/p>\n\n\n\n<p><strong>Go on a weekday morning.<\/strong> The stores get hammered on weekends during back-to-school. Tuesday or Wednesday morning is your best bet for short lines, available staff, and a less chaotic fitting experience.<\/p>\n\n\n\n<p><strong>Measure your kids' feet at home first.<\/strong> Use a printable size chart from any shoe brand's website. Knowing their size before you walk in saves 15 minutes of in-store measuring and lets you grab boxes faster.<\/p>\n\n\n\n<p><strong>Buy a half size up for growing kids.<\/strong> If your kid is between sizes, go up. They'll grow into them within a month or two. Buying the exact size means you'll be back at the store by October.<\/p>\n\n\n\n<p><strong>Stack your discounts.<\/strong> Rewards coupon + BOGO Free + tax-free weekend (if your state has one). This triple stack can drop your per-pair cost to under $25 for kids' shoes. That's hard to beat anywhere.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Check Price Matching and Coupon Stacking Policies<\/h2>\n\n\n\n<p>Rack Room doesn't formally price match competitors. If Nike.com has the same shoe for $10 less, Rack Room won't match it. But their BOGO deals often make up for this gap, especially on multi-pair purchases.<\/p>\n\n\n\n<p>As for coupon stacking, here's how it generally works:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Rewards + BOGO:<\/strong> Yes, you can use your $15 rewards credit on top of a BOGO deal.<\/li>\n<li><strong>Birthday reward + BOGO:<\/strong> Yes, the $10 birthday reward stacks with BOGO.<\/li>\n<li><strong>App coupon + BOGO:<\/strong> Sometimes. Read the coupon's exclusions carefully. Some specifically exclude BOGO purchases.<\/li>\n<li><strong>Multiple coupons:<\/strong> Generally one coupon per transaction. You can't stack two percentage-off coupons.<\/li>\n<\/ul>\n\n\n\n<p>The most reliable stack is rewards credit + BOGO. That combination works every time and is the easiest way to maximize your savings on a multi-pair purchase.<\/p>\n\n\n\n<p>One last tip: if you're making a large purchase (three or more pairs), ask the cashier if there are any current promotions you might be missing. Store associates sometimes have access to coupons or deals that aren't advertised online. It doesn't always work, but it costs nothing to ask.<\/p><div id=\"relatedsearches2\" class=\"every-content-5\"><script>console.log(\"RSOC bottom loading..\");<\/script>\r\n<\/div><script type=\"text\/javascript\" charset=\"utf-8\">\r\n    console.log('[DEBUG] Ad script block started');\r\n\r\n    \/\/ Debug function to log important events and states\r\n    function debugLog(type, message, data = null) {\r\n        const timestamp = new Date().toISOString();\r\n        console.log(`[${timestamp}] [${type}]`, message);\r\n        if (data) {\r\n            console.log('Debug data:', data);\r\n        }\r\n    }\r\n\r\n    \/\/ Validate required parameters before initialization\r\n    function validateConfig(config) {\r\n        const required = ['pubId', 'styleId', 'relatedSearchTargeting', 'resultsPageBaseUrl'];\r\n        const missing = required.filter(param => !config[param]);\r\n        \r\n        if (missing.length > 0) {\r\n            throw new Error(`Missing required parameters: ${missing.join(', ')}`);\r\n        }\r\n        \r\n        if (config.relatedSearchTargeting !== 'content' && config.relatedSearchTargeting !== 'query') {\r\n            throw new Error('relatedSearchTargeting must be either \"content\" or \"query\"');\r\n        }\r\n        \r\n        return true;\r\n    }\r\n\r\n    \/\/ Enhanced URL parameter parsing function with title fallback for referrerAdCreative\r\n    function getUrlParameter(name, defaultValue = '') {\r\n        try {\r\n            const urlParams = new URLSearchParams(window.location.search);\r\n            const value = urlParams.get(name);\r\n            \r\n            \/\/ Special handling for referrerAdCreative\r\n            if (name === 'referrerAdCreative' && !value) {\r\n                let siteTitle = document.title || defaultValue;\r\n                \r\n                \/\/ Clean up the site title if needed\r\n                if (siteTitle !== defaultValue) {\r\n                    siteTitle = siteTitle.replace(' \u2013 Everyday Guide \u2013 Your Source of Information for Daily Topics!', '').trim();\r\n                    debugLog('WARNING', 'Using modified page title as fallback for referrerAdCreative', {\r\n                        originalTitle: document.title,\r\n                        cleanedTitle: siteTitle,\r\n                        source: 'document.title'\r\n                    });\r\n                    return siteTitle;\r\n                }\r\n            }\r\n            \r\n            return value ? decodeURIComponent(value) : defaultValue;\r\n        } catch (error) {\r\n            debugLog('ERROR', `Failed to parse URL parameter: ${name}`, error);\r\n            return defaultValue;\r\n        }\r\n    }\r\n\r\n    \/\/ Add tracking domain and CID handling with validation\r\n    function getTrackingParams() {\r\n        const trackingDomain = getUrlParameter('td', '');\r\n        const cid = getUrlParameter('cid', '');\r\n        \r\n        \/\/ Only validate if tracking domain is provided\r\n        if (trackingDomain && !trackingDomain.match(\/^[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\/)) {\r\n            debugLog('WARNING', 'Invalid tracking domain format', {\r\n                provided: trackingDomain\r\n            });\r\n            return {\r\n                trackingDomain: '',\r\n                cid: cid\r\n            };\r\n        }\r\n        \r\n        return {\r\n            trackingDomain: trackingDomain,\r\n            cid: cid\r\n        };\r\n    }\r\n\r\n    const { trackingDomain, cid } = getTrackingParams();\r\n\r\n    \/\/ Get parameters from URL with defaults\r\n    const urlStyleId = getUrlParameter('styleid', '9024836547');\r\n    const urlTerms = getUrlParameter('terms', '');\r\n    const urlChannel = getUrlParameter('channel', '2273637055'); \/\/ edg 1871989443\r\n    const urlAdTitle = getUrlParameter('adtitle', '');\r\n    const urlCpid = getUrlParameter('cpid', '');\r\n    const urlOid = getUrlParameter('oid', '');\r\n\r\n    \/\/ Set tracking IDs immediately at script start, before any async operations\r\n    \/\/ Only call set_tracking_ids if it exists (tracker.js has initialized)\r\n    try {\r\n        \/\/ Debug tracker state\r\n        const trackerState = window._trackerInternalState || {};\r\n        const hasTrackerFunction = typeof window.set_tracking_ids === 'function';\r\n        const sessionData = sessionStorage.getItem('ctrkr_click_data');\r\n        let parsedSessionData = null;\r\n        try { parsedSessionData = sessionData ? JSON.parse(sessionData) : null; } catch(e) {}\r\n        \r\n        debugLog('TRACKING_DEBUG', 'Tracker state before setting IDs', {\r\n            trackerInitialized: trackerState.ready === true,\r\n            hasSetTrackingFunction: hasTrackerFunction,\r\n            hasSessionStorage: !!sessionStorage,\r\n            hasSessionData: !!sessionData,\r\n            clickId: parsedSessionData?.clickId,\r\n            existingParams: parsedSessionData?.adParams\r\n        });\r\n        \r\n        if (hasTrackerFunction) {\r\n            window.set_tracking_ids({\r\n                ad_client_id: \"partner-pub-9681717277196944\", \/\/ Your AdSense publisher ID\r\n                style_id: urlStyleId,\r\n                channel_id: urlChannel\r\n            });\r\n            \r\n            \/\/ Check if the params were actually set\r\n            setTimeout(() => {\r\n                try {\r\n                    const afterSessionData = sessionStorage.getItem('ctrkr_click_data');\r\n                    let afterParsedData = null;\r\n                    try { afterParsedData = afterSessionData ? JSON.parse(afterSessionData) : null; } catch(e) {}\r\n                    \r\n                    debugLog('TRACKING_DEBUG', 'Tracker state after setting IDs', {\r\n                        hasSessionData: !!afterSessionData,\r\n                        clickId: afterParsedData?.clickId,\r\n                        updatedParams: afterParsedData?.adParams\r\n                    });\r\n                } catch (e) {\r\n                    debugLog('TRACKING_DEBUG', 'Error checking session after update', e);\r\n                }\r\n            }, 50);\r\n            \r\n            debugLog('TRACKING', 'Successfully called set_tracking_ids');\r\n        } else {\r\n            debugLog('TRACKING', 'Tracker set_tracking_ids function not available');\r\n        }\r\n    } catch (e) {\r\n        debugLog('TRACKING_ERROR', 'Error in tracking setup', e);\r\n    }\r\n\r\n    \/\/ Define base URL constant\r\n    const BASE_RESULTS_URL = \"https:\/\/www.everyday-guide.com\/site\/search-results\/\";\r\n\r\n    \/\/ Page level configuration for related searches\r\n    var pageOptions = {\r\n        \/\/ Required Parameters\r\n        \"pubId\": \"partner-pub-9681717277196944\",    \/\/ Your AdSense publisher ID\r\n        \"styleId\": urlStyleId,                       \/\/ From URL or default\r\n        \"relatedSearchTargeting\": \"content\",         \/\/ Must use 'content' for content pages\r\n        \"resultsPageBaseUrl\": BASE_RESULTS_URL,      \/\/ Placeholder, will be finalized later\r\n        \"resultsPageQueryParam\": \"q\",\r\n        \/\/\"ivt\": false,\r\n        \/\/ Safety and Filtering\r\n        \"adsafe\": \"low\",\r\n        \/\/\"adtest\": \"off\",\r\n        \"terms\": \"\",\r\n        \"referrerAdCreative\": \"\",\r\n\r\n        \/\/ Tracking and Analytics\r\n        \"channel\": urlChannel,                       \/\/ From URL or default\r\n        \r\n        \/\/ Additional Settings\r\n        'ignoredPageParams': Array.from(new URLSearchParams(location.search).keys()).join(', '),\r\n\r\n        \/\/ Callback function for ad loading\r\n        \"adLoadedCallback\": function(containerName, adsLoaded, isExperimentVariant, callbackOptions) {\r\n            try {\r\n                \/\/ Find the container element\r\n                const container = document.getElementById(containerName);\r\n                if (!container) {\r\n                    debugLog('ERROR', `Container not found: ${containerName}`);\r\n                    return;\r\n                }\r\n\r\n                \/\/ Find the overlay within this container\r\n                const overlay = container.querySelector('.skeleton-overlay');\r\n\r\n                \/\/ Fade out and remove the overlay\r\n                if (overlay && overlay.classList.contains('skeleton-visible')) {\r\n                    overlay.classList.remove('skeleton-visible'); \/\/ Start fade out\r\n                    debugLog('SKELETON', `Fading out overlay in ${containerName}`);\r\n\r\n                    \/\/ Remove from DOM after transition\r\n                    setTimeout(() => {\r\n                        if (overlay) { \/\/ Check if it still exists\r\n                             overlay.remove();\r\n                             debugLog('SKELETON', `Removed overlay from DOM in ${containerName}`);\r\n                        }\r\n                    }, 300); \/\/ Match CSS transition duration\r\n                }\r\n\r\n                if (adsLoaded && callbackOptions && callbackOptions.termPositions) {\r\n                    const terms = Object.keys(callbackOptions.termPositions);\r\n                    console.log('Related Search Terms Shown:', terms);\r\n                    console.log('Term Positions:', callbackOptions.termPositions);\r\n                }\r\n                \r\n                debugLog('CALLBACK', `Container: ${containerName}`, {\r\n                    adsLoaded,\r\n                    isExperimentVariant,\r\n                    callbackOptions\r\n                });\r\n\r\n                if (adsLoaded) {\r\n                    debugLog('SUCCESS', 'Related searches loaded successfully');\r\n                    \/\/ Remove legacy tracking call\r\n                    \/\/ window.trackEvent('adview');\r\n                    \/\/ Debug tracking state before sending event\r\n                    try {\r\n                        const eventSessionData = sessionStorage.getItem('ctrkr_click_data');\r\n                        let eventParsedData = null;\r\n                        try { eventParsedData = eventSessionData ? JSON.parse(eventSessionData) : null; } catch(e) {}\r\n                        \r\n                        debugLog('TRACKING_EVENT', 'State before ad_view event', {\r\n                            hasSessionData: !!eventSessionData,\r\n                            clickId: eventParsedData?.clickId,\r\n                            params: eventParsedData?.adParams\r\n                        });\r\n                    } catch (e) {\r\n                        debugLog('TRACKING_ERROR', 'Error checking session before event', e);\r\n                    }\r\n                    \r\n                    \/\/ Send tracking event using new API with parameters as fallback\r\n                    window.track_event('ad_view', {});\r\n                    \/\/ Track Facebook Pixel ViewContent event\r\n                    fbq('track', 'ViewContent');\r\n                    \r\n                    \/\/ Log terms and their positions if available\r\n                    if (callbackOptions && callbackOptions.termPositions) {\r\n                        console.log('Related Search Terms:', Object.keys(callbackOptions.termPositions));\r\n                        console.log('Term Positions:', callbackOptions.termPositions);\r\n                    }\r\n                    \r\n                    \/\/ Log container dimensions for debugging layout issues\r\n                    const rect = container.getBoundingClientRect();\r\n                    debugLog('LAYOUT', 'Container dimensions', {\r\n                        width: rect.width,\r\n                        height: rect.height,\r\n                        visible: rect.height > 0\r\n                    });\r\n                } else {\r\n                    debugLog('WARNING', 'No related searches available');\r\n                    container.style.display = 'none';\r\n                    \/\/ Remove legacy tracking call\r\n                    \/\/ window.trackEvent('noresult');\r\n                    \/\/ Debug tracking state before sending event\r\n                    try {\r\n                        const eventSessionData = sessionStorage.getItem('ctrkr_click_data');\r\n                        let eventParsedData = null;\r\n                        try { eventParsedData = eventSessionData ? JSON.parse(eventSessionData) : null; } catch(e) {}\r\n                        \r\n                        debugLog('TRACKING_EVENT', 'State before no_result event', {\r\n                            hasSessionData: !!eventSessionData,\r\n                            clickId: eventParsedData?.clickId,\r\n                            params: eventParsedData?.adParams\r\n                        });\r\n                    } catch (e) {\r\n                        debugLog('TRACKING_ERROR', 'Error checking session before event', e);\r\n                    }\r\n                    \r\n                    \/\/ Send tracking event using new API with parameters as fallback\r\n                    window.track_event('rsoc_not_monetized', {});\r\n                    \r\n                    \/\/ Log possible reasons for no results\r\n                    debugLog('DEBUG', 'Checking possible issues', {\r\n                        url: window.location.href,\r\n                        containerExists: !!container,\r\n                        containerVisible: container.offsetParent !== null,\r\n                        pageContent: document.body.textContent.length\r\n                    });\r\n                }\r\n            } catch (error) {\r\n                debugLog('ERROR', 'Error in callback', {\r\n                    message: error.message,\r\n                    stack: error.stack\r\n                });\r\n            }\r\n        }\r\n    };\r\n\r\n    \/\/ Configuration for the related searches containers\r\n    const rsblock1 = {\r\n        \/\/ Required Parameters\r\n        \"container\": \"relatedsearches1\",\r\n        \"width\": 700,\r\n        \r\n        \/\/ Optional Parameters\r\n        \"relatedSearches\": 6,\r\n        \r\n        \/\/ Reference to the callback in pageOptions\r\n        \"adLoadedCallback\": pageOptions.adLoadedCallback\r\n    };\r\n\r\n    const rsblock2 = {\r\n        \/\/ Required Parameters\r\n        \"container\": \"relatedsearches2\",\r\n        \"width\": 700,\r\n        \r\n        \/\/ Optional Parameters\r\n        \"relatedSearches\": 6,\r\n        \r\n        \/\/ Reference to the callback in pageOptions\r\n        \"adLoadedCallback\": pageOptions.adLoadedCallback\r\n    };\r\n\r\n    \/\/ --- Ad Initialization Logic ---\r\n\r\n    let adsInitialized = false;\r\n    const AD_INIT_TIMEOUT = 2500; \/\/ Timeout in milliseconds (e.g., 2.5 seconds)\r\n    let initTimeoutId = null;\r\n\r\n    \/\/ Function to inject skeleton overlay SYNCHRONOUSLY\r\n    function injectSkeletonOverlay(containerId) {\r\n        const container = document.getElementById(containerId);\r\n        if (container) {\r\n            if (!container.querySelector('.skeleton-overlay')) {\r\n                const overlay = document.createElement('div');\r\n                overlay.className = 'skeleton-overlay skeleton-visible';\r\n                container.appendChild(overlay);\r\n                debugLog('SKELETON', `Injected overlay into ${containerId}`);\r\n            } else {\r\n                debugLog('SKELETON', `Overlay already exists in ${containerId}`);\r\n            }\r\n        } else {\r\n            debugLog('WARNING', `Container ${containerId} not found for overlay injection.`);\r\n        }\r\n    }\r\n\r\n    \/\/ Function to hide skeletons if initialization fails\r\n    function hideSkeletonsOnError() {\r\n        ['relatedsearches1', 'relatedsearches2'].forEach(containerId => {\r\n            const container = document.getElementById(containerId);\r\n            const overlay = container?.querySelector('.skeleton-overlay.skeleton-visible');\r\n            if (overlay) {\r\n                overlay.classList.remove('skeleton-visible');\r\n                \/\/ Optionally remove after fade, but maybe just hide on error\r\n                debugLog('SKELETON', `Hiding overlay in ${containerId} due to init error.`);\r\n            }\r\n            \/\/ Also hide the main container if ads fail to load\r\n            if(container) container.style.display = 'none';\r\n        });\r\n    }\r\n\r\n    \/\/ Main function to initialize Google CSA ads\r\n    function initializeGoogleAds() {\r\n        if (adsInitialized) return; \/\/ Prevent double initialization\r\n        adsInitialized = true;\r\n        clearTimeout(initTimeoutId); \/\/ Clear the timeout if event fired\r\n        debugLog('ADS_INIT', 'Proceeding with _googCsa initialization.');\r\n\r\n        injectSkeletonOverlay('relatedsearches1');\r\n        injectSkeletonOverlay('relatedsearches2');\r\n\r\n        \/\/ Re-evaluate tracking params based on the final state from event-tracker.js\r\n        const trackerState = window._trackerInternalState || {};\r\n        const finalCid = trackerState.clickId || getUrlParameter('cid', ''); \/\/ Use state's CID or fallback to original URL param\r\n        \/\/ Note: Tracking domain (td) is primarily used by event-tracker, but include if needed for URL construction\r\n        const finalTd = (trackerState.trackingMethod === 'redirect' ? trackerState.domain : null) || getUrlParameter('td', ''); \/\/ Get TD if redirect, else fallback\r\n        \r\n        \/\/ Tracking IDs already set at the beginning of script\r\n\r\n        \/\/ Re-construct the results URL using the potentially updated CID\/TD\r\n        pageOptions.resultsPageBaseUrl = BASE_RESULTS_URL;\r\n        debugLog('ADS_INIT', 'Final resultsPageBaseUrl:', { url: pageOptions.resultsPageBaseUrl });\r\n\r\n        \/\/ Add referrerAdCreative only if urlAdTitle has a value (moved here to be part of final options)\r\n        if (urlAdTitle) {\r\n            pageOptions.referrerAdCreative = urlAdTitle;\r\n            debugLog('INFO', 'referrerAdCreative parameter included in configuration', { referrerAdCreative: urlAdTitle });\r\n        } else {\r\n            delete pageOptions.referrerAdCreative;\r\n            debugLog('INFO', 'No referrerAdCreative parameter provided, removed from configuration');\r\n        }\r\n\r\n        \/\/ Add terms if provided (moved here)\r\n        if (urlTerms) {\r\n            pageOptions.terms = urlTerms;\r\n        }\r\n\r\n        \/\/ Update ignoredPageParams (moved here)\r\n        pageOptions.ignoredPageParams = Array.from(new URLSearchParams(location.search).keys()).join(', ');\r\n\r\n        \/\/ Debug log all parameters before initialization\r\n        debugLog('PARAMS', 'Page Options Configuration:', {\r\n            \/\/ Required Parameters\r\n            pubId: pageOptions.pubId,\r\n            styleId: pageOptions.styleId,\r\n            relatedSearchTargeting: pageOptions.relatedSearchTargeting,\r\n            resultsPageBaseUrl: pageOptions.resultsPageBaseUrl,\r\n            resultsPageQueryParam: pageOptions.resultsPageQueryParam,\r\n            referrerAdCreative: pageOptions.referrerAdCreative,\r\n            \r\n            \/\/ Optional Parameters\r\n            terms: pageOptions.terms || '(not set)',\r\n            maxTermLength: pageOptions.maxTermLength,\r\n            linkTarget: pageOptions.linkTarget,\r\n            \r\n            \/\/ Safety and Filtering\r\n            adsafe: pageOptions.adsafe,\r\n            adtest: pageOptions.adtest,\r\n            ivt: pageOptions.ivt,\r\n            \r\n            \/\/ Language and Encoding\r\n            hl: pageOptions.hl,\r\n            \r\n            \/\/ Tracking and Analytics\r\n            channel: pageOptions.channel,\r\n            \r\n            \/\/ Container Configurations\r\n            containerSettings: {\r\n                block1: {\r\n                    container: rsblock1.container,\r\n                    width: rsblock1.width,\r\n                    relatedSearches: rsblock1.relatedSearches\r\n                },\r\n                block2: {\r\n                    container: rsblock2.container,\r\n                    width: rsblock2.width,\r\n                    relatedSearches: rsblock2.relatedSearches\r\n                }\r\n            }\r\n        });\r\n\r\n        \/\/ --- Call Google CSA ---\r\n        try {\r\n            verifyScriptLoading(); \/\/ Verify dependent scripts\r\n            validateConfig(pageOptions); \/\/ Validate final config\r\n\r\n            \/\/ Log the final pageOptions before initialization\r\n            console.log('[DEBUG] Final pageOptions just before _googCsa:', JSON.stringify(pageOptions, null, 2));\r\n\r\n            _googCsa('relatedsearch', pageOptions, rsblock1, rsblock2);\r\n            debugLog('ADS_INIT', '_googCsa called successfully.');\r\n\r\n        } catch (error) {\r\n            console.error('[ERROR] Google CSA Initialization Failed!', error);\r\n            debugLog('ERROR', 'Google CSA Initialization failed', {\r\n                message: error.message,\r\n                stack: error.stack\r\n            });\r\n            \/\/ Hide skeletons and containers on error\r\n            hideSkeletonsOnError();\r\n        }\r\n    }\r\n\r\n    \/\/ --- Event Listener and Timeout --- \r\n\r\n    \/\/ Check if tracker is already ready *before* setting up listener\/timeout\r\n    if (window._trackerInternalState?.ready) {\r\n        debugLog('ADS_INIT', 'Tracker was already ready. Initializing ads immediately.');\r\n        initializeGoogleAds();\r\n    } else {\r\n        debugLog('ADS_INIT', 'Tracker not ready yet. Setting up listener and timeout.');\r\n\r\n        \/\/ Listener for the tracker signal\r\n        const trackerListener = (event) => {\r\n            debugLog('ADS_INIT', 'Received trackerInitialized event', event.detail);\r\n            window.removeEventListener('trackerInitialized', trackerListener); \/\/ Clean up listener\r\n            initializeGoogleAds();\r\n        };\r\n        window.addEventListener('trackerInitialized', trackerListener);\r\n\r\n        \/\/ Timeout fallback: Initialize ads if the tracker event doesn't arrive promptly\r\n        initTimeoutId = setTimeout(() => {\r\n            debugLog('ADS_INIT', `Timeout waiting for trackerInitialized event after ${AD_INIT_TIMEOUT}ms. Proceeding.`);\r\n            window.removeEventListener('trackerInitialized', trackerListener); \/\/ Clean up listener if timeout fires first\r\n            initializeGoogleAds();\r\n        }, AD_INIT_TIMEOUT);\r\n    }\r\n\r\n    \/\/ Add script loading verification\r\n    function verifyScriptLoading() {\r\n        debugLog('SCRIPT', 'Entering verifyScriptLoading');\r\n        debugLog('SCRIPT', 'Checking script loading status', {\r\n            adsScriptLoaded: !!document.querySelector('script[src*=\"ads.js\"]'),\r\n            googCsaAvailable: typeof _googCsa === 'function'\r\n        });\r\n        debugLog('SCRIPT', 'Exiting verifyScriptLoading');\r\n    }\r\n\r\n    \/\/ --- Modify constructUrlWithTracking to accept parameters --- \r\n    \/\/ (Keep the original getTrackingParams for initial values if needed elsewhere, or remove if redundant)\r\n    function constructUrlWithTracking(baseUrl, cid, td, styleid, channel) {\r\n        try {\r\n            const url = new URL(baseUrl);\r\n            \/\/ Add parameters if they exist\r\n            if (td) url.searchParams.set('td', td);\r\n            if (cid) url.searchParams.set('cid', cid);\r\n            if (styleid) url.searchParams.set('styleid', styleid);\r\n            if (channel) url.searchParams.set('channel', channel);\r\n            return url.toString();\r\n        } catch (error) {\r\n            debugLog('ERROR', 'Failed to construct results page URL with tracking parameters', {\r\n                baseUrl,\r\n                error: error.message\r\n            });\r\n            return baseUrl;\r\n        }\r\n    }\r\n\r\n<\/script>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Bottom Line<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.everyday-guide.com\/site\/v73k\" title=\"Rack Room Shoes\" class=\"pretty-link-keyword\"rel=\"nofollow sponsored \" target=\"_blank\">Rack Room Shoes<\/a> isn't the cheapest <a href=\"https:\/\/www.everyday-guide.com\/site\/v73k\" title=\"Rack Room Shoes\" class=\"pretty-link-keyword\"rel=\"nofollow sponsored \" target=\"_blank\">shoe store<\/a> on any given day. Their individual prices are middle-of-the-road. But when you stack their BOGO deals with rewards, app coupons, clearance markdowns, and smart timing, the total cost drops fast. The key is going in with a plan rather than just wandering in and buying whatever catches your eye.<\/p>\n\n\n\n<p>The biggest savings come from buying multiple pairs during back-to-school or Black Friday events, using ship to store to avoid shipping fees, and keeping your rewards account active so you don't miss free birthday money. None of these tricks require extreme couponing skills. They just require a little patience and awareness of when the good deals hit.<\/p>\n\n\n\n<p><strong>Join the rewards program, download the app, time your purchases around BOGO Free events, and don't ignore clearance. Do those four things and you'll pay 30-50% less than the average Rack Room shopper.<\/strong><\/p>\n      <div class=\"prli-link-to-disclosures\">\n        <a href=\"https:\/\/www.everyday-guide.com\/site\/disclaimer\/\">(*)This post contains affiliate links. If you use these links to buy something we may earn a commission. Thanks.<\/a>\n      <\/div>\n      ","protected":false},"excerpt":{"rendered":"<p>Rack Room&#8217;s BOGO deals run almost year-round, but timing your purchase around key sales events can stack your savings even further. Their rewards program, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":40207,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[105,28],"tags":[],"class_list":["post-39741","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-buying-guide","category-fashion"],"_links":{"self":[{"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/posts\/39741","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/comments?post=39741"}],"version-history":[{"count":0,"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/posts\/39741\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/media\/40207"}],"wp:attachment":[{"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/media?parent=39741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/categories?post=39741"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.everyday-guide.com\/site\/wp-json\/wp\/v2\/tags?post=39741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}