May 28, 2025
Subscriber in Audience But No Email: The Not Sent Diagnosis Checklist
Audience has 50k subscribers. Email Sent shows 48,200. Client asks why 1,800 people didn't get the email. Six reasons cover 99% of cases. Run them in order.
Read MoreThe Marketing Cloud Personalization sitemap.js is where most production implementations break. Five gotchas that consume the bulk of debugging time on real engagements: SPA route changes, async data, item attribution, modal contexts, and beacon timing.

The catalog defines what Marketing Cloud Personalization knows. The sitemap.js defines what it sees. On every production engagement, the data-layer file is the source of more debugging time than every other component combined. Four reasons recur. A fifth shows up only when the implementation looks done, which is when it gets shipped.
Single-page applications navigate without a full page reload. The browser URL changes, content swaps, but no new page-load event fires. Default sitemap.js implementations that hook into page-load see one event for the entire session.
The symptom is that visitors look like they spent 40 minutes on the home page and never visited a product. Affinity learning starves. Recommendation quality stays at cold-start levels even after weeks of traffic.
Two fixes work, and exactly one of them is the right one for any given site:
Whichever path is chosen, the test is identical. Open the network tab, click through five pages without reloading. Five distinct beacons should fire, each with the correct page type. If only one fires on initial load, the integration is silently broken.
Product pages on modern sites render the layout first, then fetch product data via XHR or GraphQL, then update the DOM. Sitemap.js typically reads from the DOM at page-load time. On async-rendered pages, that read happens before the data is there.
The result is beacons that fire with itemId: null or with placeholder values from the layout shell. The platform attributes the visit to nothing, or worse, to a phantom item that never gets cataloged.
Three patterns are reliable, in order of preference:
Avoid setTimeout-with-arbitrary-delay. It works on a fast connection and breaks on a slow one, which means it works in dev and breaks in production.
The catalog stores items keyed by the canonical product ID. The product detail page DOM might expose:
Reading the wrong one means every beacon attributes to the wrong identity. Affinity profiles split across ghost variants. Recommendations target items that do not exist in the catalog.
The discipline is to confirm the DOM source matches the catalog ID column, in writing, before any traffic flows. The five-minute conversation: "what attribute does the product page expose, and is that the same field used as item ID in the catalog feed?" That conversation prevents months of bad data.
When variants exist, decide upfront whether the platform tracks at parent SKU or variant level. Both are defensible. Mixed is not. Pick one, document it, configure the catalog and the sitemap consistently.
Most sitemap.js code assumes one page type per page load. On a category listing page, that is "category." On a product detail page, that is "item-detail." The platform learns from this and recommends accordingly.
Then a quick-view modal opens. The visitor is now looking at product detail content while the URL still shows the category. Default sitemaps fire nothing for the modal, or fire the wrong event, or double-fire and the platform sees two competing contexts.
The fix is explicit modal handling:
Without this discipline, sites with heavy quick-view usage end up with category pages that look like nothing happened, even when visitors are deep-diving on individual products through modals.
A view event with no timing rule fires the moment the page loads. On a product detail page, that means a 0.4-second visitor who hits back immediately gets counted as a viewer. Recommendation models trained on that data optimize for accidental clicks.
A few timing patterns work well:
Listing pages are the opposite. There, the platform wants to know what items the visitor saw without forcing each one to be hovered. The right pattern is impression beacons keyed off intersection observers, fired once per item per visit, gated on the product card being at least partially visible.
The default behavior in most starter sitemaps is to fire instantly on page load. The cost is recommendation models that overfit on noise. The fix is two hours of timing logic per page type.
When MCP behavior looks wrong, the sitemap is the most likely cause. The order to check:
A clean sitemap.js is the single highest-leverage piece of an MCP implementation. Sapota's Salesforce team budgets two to three weeks for sitemap design and validation on every Personalization project, regardless of how mature the existing analytics layer looks.
Building or debugging an MCP sitemap? Sapota's Salesforce team handles data-layer design, beacon validation, and SPA integration on production engagements. Get in touch ->
See our full platform services for the stack we cover.
We build trust by delivering what we promise – the first time and every time!
We'd love to hear your vision. Our IT experts will reach out to you during business hours to discuss making it happen.
"Collaborate, Elevate, Celebrate where Associates - Create Project Excellence"
SapotaCorp beyond the IT industry standard, we are