Dooney & Bourke Integration
Store Details
| Field | Value |
|---|---|
| Store URL | https://www.dooney.com |
| Shopify domain | g6aze3-rt.myshopify.com |
| Marqo index | cbym3jcr-shopify-g6aze3-rt |
| Storefront API key | stored in tmp/integrations/dooney-bourke/ (not in docs) |
| Marqo debug header | x-marqo-debug: 6F188718-DC08-4076-9E05-434CC7E728C3 |
| DynamoDB table | prod-ShopifyEntitiesTable |
| AWS profile | controller |
| Shopify access token | retrieved from DDB at runtime via scripts/ecom/shopify_graphql.py |
| Settings backups | tmp/integrations/dooney-bourke/backup*.json |
Theme IDs
| Theme | ID | Role | Notes |
|---|---|---|---|
| Native published | 175084241195 | MAIN | "Main Branch: Dooney and Bourke" — the live customer-facing theme |
| NEW Marqo | 188674638123 | UNPUBLISHED | "June 18, 2026 | Dooney & Bourke <> Marqo" — created 2026-06-18 |
| OLD Marqo | 188218507563 | UNPUBLISHED | "Marqo Theme (Dooney & Burke)" — older Marqo theme; both themes now share the same template state |
Preview URLs
Each unpublished theme has its own *.shopifypreview.com session token. The URL is bound to one theme — the ?preview_theme_id= query parameter is dropped on redirect, so you cannot switch themes through the same preview URL. To get a fresh URL, open Shopify Admin → Themes → "..." → Preview on the target theme.
- NEW Marqo preview:
https://bvgn370aic0x79vw-91717239083.shopifypreview.com - OLD Marqo preview:
https://kfxs8t4qp6x6f8ag-91717239083.shopifypreview.com
Status
- Index created and populated (
cbym3jcr-shopify-g6aze3-rt, ~1185 products across collections) - App embed enabled on both Marqo themes
- App blocks inserted into 18 collection templates +
search.jsonon both Marqo themes (see Theme Templates below) -
collection-products(native) sections disabled where marqo block was injected -
show_heading: falseset on marqo block of 18 collection templates (kept defaulttrueon search) - Filter sidebar default hidden (
defaultVisibility = {"search":"hidden","collection":"hidden"}) - Grid columns: 3 desktop / 2 tablet / 2 mobile
- PowerReviews integration (provider
powerreviews, calls merchant'sloadPowerReviews()to hydrate) - Variant collapse via
collapseFields = [{"name":"parentProductId"}]oncollections_config.default - Swatches
imageSource = swatchHandleFile - CTA enabled and styled (Layer 3 CSS in
custom_css) - Custom filter CSS appended to
custom_css.value.css - Navbar menu handle pointed at the active
main-menu-6-18 - Product badges (PR #3819 pending merge + deploy)
- Partial-swatch bug (4 products show variant photo as swatch tile — fix in flight: bulk-sync enrichment rebuild)
- Search form action repoint (form submits to
/collections/shop, bypasses Marqo search.json — under investigation)
Critical Gotchas — read these before touching anything
1. Search form action goes to /collections/shop, not /search
Dooney's theme hardcodes the header search form's action attribute to /collections/shop. When a user submits the search bar, the browser navigates to /collections/shop?q=... — not /search?q=.... This is part of the merchant's pre-existing Searchspring integration.
Consequence: templates/search.json (which we inject Marqo into) is never hit by the search bar. The page that loads renders the "shop" collection via Marqo (or via Searchspring's takeover on the published theme). Marqo's widget does not currently interpret the q= URL param as a search query when it's on a collection page.
Fix path (not yet shipped): change the form's action to /search in the merchant's theme template (one-line edit; merchant theme file). Then our existing search.json injection takes over and search works end-to-end.
2. Header menu handle is version-bumped frequently
The header's nav links are populated from a Shopify shop-level linklist whose handle the merchant version-bumps every theme release. On 2026-06-18 the merchant moved from main-menu-6-17 to main-menu-6-18 and emptied the older versions. Our Marqo themes' header-refector.settings.menu reference was pointing at the OLDER handle, so the navbar rendered with the section wrapper but zero menu items.
Where this is set: sections/header-group.json → sections["header_refector_<id>"].settings.menu on each theme. The enabled header_refector instance differs per theme (pnd8zj on OLD, BhfjGr on NEW); both now point at main-menu-6-18 matching LIVE.
If the navbar empties out again, check whether the merchant version-bumped to a new handle and update both Marqo themes to match.
Diagnostic recipe:
# Count rendered nav items per theme
curl -s "<preview-url>/collections/the-heritage-collection" | grep -c main-nav__item
# LIVE control:
curl -s "https://www.dooney.com/collections/the-heritage-collection" | grep -c main-nav__item
3. Klaviyo popup adds klaviyo-prevent-body-scrolling class to <body>
The naive dismiss snippet document.querySelectorAll('[id*="klaviyo"], [class*="klaviyo"]').forEach(el => el.style.display = 'none') will match the <body> element and set the whole page to display: none. Marqo cards render correctly behind the modal — the page just goes blank if you run that snippet without a tag guard.
Use this safer snippet:
document.querySelectorAll('[id*="klaviyo"], [class*="klaviyo"]').forEach(el => {
if (el.tagName !== 'BODY' && el.tagName !== 'HTML' && el.getBoundingClientRect().width > 200) {
el.style.display = 'none';
}
});
4. Swatch fix is partial on the bulk-sync path
After deploying PR #3796 (tileImageUrl resolver) and PR #3813 (siblingSwatchHandles indexer field), only products that subsequently went through the webhook path (single-product reindex via a Shopify admin variant edit) ended up with correct siblingSwatchHandles. Products reindexed only through bulk sync still have ['[""]', '[""]', ...] empty siblings and render the full variant photo as the swatch tile.
Root cause: bulk_operations_mutations.py:89-115 omits variants.metafields in the bulk export query (to avoid Shopify's 5-connection nesting cap; Royal Distributing previously hit it). The enrichment step patches the rolled-up variantMetafieldCustomSwatchHandle field but doesn't rebuild the ordered per-sibling siblingSwatchHandles.
Do NOT trigger a Dooney resync as a remediation — the bulk path is the bug; resyncing will REGRESS any product that was previously correct.
Fix in flight: extend _apply_enrichment_to_docs in bulk_sync_handler.py to rebuild siblingSwatchHandles from variant_metafields_map, which the enrichment step already fetches. See tmp/integrations/dooney-bourke/escalations/swatches-partial-r2.md for the full diagnosis.
Affected product handles: heritage-messenger-18-bheri2587, heritage-messenger-20-bheri2588, heritage-hobo-23-bheri2589, heritage-drawstring-20-bheri2590. Control product (still correct): heritage-domed-crossbody-18-bheri2585.
5. Storefront bundle deploys are manual
Deploy & Test Shopify is the only workflow that builds + uploads s3://.../search/bundle.js. It has no push: main trigger and the Ecommerce Pipeline does not call it. Bundle deploys for storefront_search PRs require an explicit manual fire of that workflow. If a PR you merged isn't reflected on the live preview, check last-modified on https://d1cn6wu7hc977d.cloudfront.net/search/bundle.js against the PR merge time before chasing code.
Theme Templates (Marqo themes)
19 templates have a marqo apps section injected:
templates/search.json(1 — mainmain-searchsection disabled)templates/collection.json(1 — maincollection-productssection disabled,show_heading: false)- 17 named
templates/collection.<name>.json— same pattern ascollection.json
3 templates remain untouched (editorial layouts with collection-products already disabled, no products grid visible):
templates/collection.sports.jsontemplates/collection.the-handwoven-hobo.jsontemplates/collection.the-salzburg-drawstring.json
Injection script: scripts/ecom/inject_marqo_blocks.py. Dooney's run command (Online Store 2.0 themes — uses the --grid-section-types opt-in flag from PR #3778):
python3 scripts/ecom/inject_marqo_blocks.py \
--shop g6aze3-rt.myshopify.com \
--theme-id <188218507563 or 188674638123> \
--token <fetched-from-DDB> \
--blocks grid \
--grid-section-types main-search,main-collection-products
Inline banners — pending merchant data authoring
Native Dooney runs Searchspring IQ Merchandising for collection PLP inline banners (banner IDs like 2165392/2165393 at fixed grid positions 6, 10 on /bags, /new-arrivals, etc.). Banner content is not in Shopify metafields today — it's served by Searchspring's API at render time.
Marqo cannot read Searchspring's banner data, but our widget already supports a metafield-driven banner path. For Dooney to keep their banners on Marqo PLPs, the merchant needs to author banner content as Shopify metaobjects/metafields. The schema and step-by-step setup is in inline-banners-metafield-spec.md (SE handoff doc, recommends custom.inline_banners as a list of plp_inline_banner metaobject references).
Once authored, Marqo picks the banners up on the next collection page load — no Marqo-side push, no widget code change, no theme integration. Full investigation: tmp/integrations/dooney-bourke/escalations/inline-banners.md.
Third-party integrations on the merchant's theme
- Searchspring — pre-existing third-party search platform; owns the search form's
action="/collections/shop". See Gotcha #1. - PowerReviews — product reviews; merchant theme exposes
window.loadPowerReviews()which Marqo's storefront_search calls per render batch. - Klaviyo — email capture popup; fires on every page load. See Gotcha #3.
- Orbe — geolocation / currency localization; sets
orbe-country-code--<XX>andorbe-language-code--<xx-XX>body classes. - Other — Google Tag Manager, Facebook Pixel (returns connection refused in headless preview), various theme blocks (
store-header,product-card,swatch-manager,swiper-container).
PRs that shipped for Dooney enablement (2026-06)
| PR | Title | Notes |
|---|---|---|
| #3778 | feat: --grid-section-types opt-in for OS2 themes in inject_marqo_blocks | Enables injecting into Dawn/OS2 themes whose products section uses non-main keys |
| #3792 | feat: Add PowerReviews provider to storefront review widget | Wires settings + provider plumbing |
| #3795 | fix: Call merchant's loadPowerReviews() to hydrate PR snippets on Marqo cards | Hooks into theme's existing PR bootstrap |
| #3796 | feat: Configurable swatch image source for OS2 themes | Adds imageSource setting + tileImageUrl resolver |
| #3811 | fix: MutationObserver strip of spurious PR tags on swatches | Cleans up PR's React engine attaching data-pr-component="CategorySnippet" to swatch inners |
| #3813 | feat: Index sibling swatch handles for OS2 swatch tiles | Adds siblingSwatchHandles field to Marqo docs |
| #3819 | feat: Generalized product badge widget (open as of writing) | Extends LG's metaobject-badge to support plain text labels |
| (in flight) | fix: Rebuild siblingSwatchHandles in bulk-sync enrichment step | Closes the swatch-fix-partial gap (Gotcha #4) |
DDB IndexSettings (production-write — requires explicit user authorization)
pk=cbym3jcr,sk=INDEX#shopify-g6aze3-rt→collections_config.default.collapseFields = [{"name": "parentProductId"}]— collapses variants to one card per parent product