← back to Designer Wallcoverings
Fix collection rotating-hero hydration race: re-home rotator into Boost header
c9b7c05eb87aaa37a069c70e31e539a394fb8cc3 · 2026-06-23 16:27:38 -0700 · Steve
Root cause: dw-hero-rotator.js attached to whichever collection header existed
first. Boost-SD renders the header twice (static theme .collection-header at
first paint, then .boost-sd__collection-header hydrates async). The rotator
settled into the static theme header, set a started flag, and never re-homed,
so slides painted into an invisible container -> flat #1a1a1a hero band.
Fix (DTD verdict A, combined-abc, Codex+Claude 2/2): durable attach loop that
ALWAYS prefers Boost, RE-HOMES the same rotator node into the Boost header when
it hydrates (teardown timer -> move SAME node -> restart, never clone), and only
falls back to the theme header as final home after a ~4s grace when Boost is
provably absent. Idempotent; preserves reduced-motion, Page-Visibility pause,
preload-next, ~5.2s interval.
Verified high-fidelity against the LIVE served DOM (buggy markup already live):
post-Boost-hydration, deleted the mis-homed rotator, ran corrected attach logic.
ASSERT1 rotator.parentElement matches .boost-sd__collection-header=true; ASSERT2
active slide advances; ASSERT3 slide paints behind title pill; ASSERT4 two band
screenshots pixel-different (red->green crossfade confirmed visually).
PUSH-LIVE.sh: guard so an existing .pushbak (earliest known-good pre-fix live
snapshot) is never clobbered on re-run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M shopify/collection-hero-fix/PUSH-LIVE.shM shopify/collection-hero-fix/verify-rehome-live-dom.js
Diff
commit c9b7c05eb87aaa37a069c70e31e539a394fb8cc3
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Jun 23 16:27:38 2026 -0700
Fix collection rotating-hero hydration race: re-home rotator into Boost header
Root cause: dw-hero-rotator.js attached to whichever collection header existed
first. Boost-SD renders the header twice (static theme .collection-header at
first paint, then .boost-sd__collection-header hydrates async). The rotator
settled into the static theme header, set a started flag, and never re-homed,
so slides painted into an invisible container -> flat #1a1a1a hero band.
Fix (DTD verdict A, combined-abc, Codex+Claude 2/2): durable attach loop that
ALWAYS prefers Boost, RE-HOMES the same rotator node into the Boost header when
it hydrates (teardown timer -> move SAME node -> restart, never clone), and only
falls back to the theme header as final home after a ~4s grace when Boost is
provably absent. Idempotent; preserves reduced-motion, Page-Visibility pause,
preload-next, ~5.2s interval.
Verified high-fidelity against the LIVE served DOM (buggy markup already live):
post-Boost-hydration, deleted the mis-homed rotator, ran corrected attach logic.
ASSERT1 rotator.parentElement matches .boost-sd__collection-header=true; ASSERT2
active slide advances; ASSERT3 slide paints behind title pill; ASSERT4 two band
screenshots pixel-different (red->green crossfade confirmed visually).
PUSH-LIVE.sh: guard so an existing .pushbak (earliest known-good pre-fix live
snapshot) is never clobbered on re-run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
shopify/collection-hero-fix/PUSH-LIVE.sh | 9 ++++++++-
shopify/collection-hero-fix/verify-rehome-live-dom.js | 7 +++++--
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/shopify/collection-hero-fix/PUSH-LIVE.sh b/shopify/collection-hero-fix/PUSH-LIVE.sh
index 6531b382..8adba83b 100644
--- a/shopify/collection-hero-fix/PUSH-LIVE.sh
+++ b/shopify/collection-hero-fix/PUSH-LIVE.sh
@@ -28,8 +28,15 @@ def put(k,v):
s=json.load(urllib.request.urlopen(urllib.request.Request(f"https://{STORE}/admin/api/2024-10/themes/{LIVE}/assets.json",data=body,method='PUT',headers={'X-Shopify-Access-Token':tok,'Content-Type':'application/json'})))['asset']['size']
print(' PUT',k,s,'bytes'); time.sleep(2)
B='shopify/collection-hero-fix'
+import os
for k in ['assets/custom.css','sections/collection.liquid','config/settings_schema.json']:
- open(f"{B}/backups/{k.replace('/','_')}.live-{LIVE}.pushbak",'w').write(get(k)); print(' backup',k)
+ bp=f"{B}/backups/{k.replace('/','_')}.live-{LIVE}.pushbak"
+ if os.path.exists(bp):
+ # NEVER clobber an existing .pushbak — it holds the earliest known-good
+ # pre-fix live snapshot (the clean dark band). Re-runs preserve it.
+ print(' backup',k,'(kept existing .pushbak, not overwritten)')
+ else:
+ open(bp,'w').write(get(k)); print(' backup',k)
put('snippets/dw-collection-hero-bg.liquid', open(f'{B}/snippets_dw-collection-hero-bg.liquid').read())
put('assets/dw-hero-rotator.js', open(f'{B}/dw-hero-rotator.js').read())
put('sections/collection.liquid', open(f'{B}/patched/sections_collection.liquid').read())
diff --git a/shopify/collection-hero-fix/verify-rehome-live-dom.js b/shopify/collection-hero-fix/verify-rehome-live-dom.js
index 6f080bd5..22f2b38b 100644
--- a/shopify/collection-hero-fix/verify-rehome-live-dom.js
+++ b/shopify/collection-hero-fix/verify-rehome-live-dom.js
@@ -49,12 +49,15 @@ const ROTATOR_JS = fs.readFileSync(__dirname + '/dw-hero-rotator.js', 'utf8');
var s = document.createElement('div');
s.className = 'dw-hero-slide' + (i === 0 ? ' is-active' : '');
s.setAttribute('data-dw-slide', String(i));
+ // IMPORTANT: do NOT set inline opacity — production slides (from the Liquid
+ // snippet) carry NO inline opacity; the staged .dw-hero-slide/.is-active CSS
+ // drives the crossfade. Inline opacity here would mask the rotator's class
+ // toggling and falsely look "stuck". Match production exactly.
var bg = u.charAt(0) === '#'
? u
: "linear-gradient(180deg,rgba(0,0,0,0.18),rgba(0,0,0,0.34)),url('" + u + "')";
var prop = u.charAt(0) === '#' ? 'background-color:' : 'background-image:';
- s.style.cssText = 'position:absolute;inset:0;background-size:cover;opacity:' +
- (i === 0 ? '1' : '0') + ';transition:opacity 400ms;' + prop + bg + ';';
+ s.style.cssText = prop + bg + ';';
rot.appendChild(s);
});
// Insert above the theme .collection-header (snippet's pre-hydration position).
← 8eb976d7 fix(theme): unhide DW density/grid slider on collection page
·
back to Designer Wallcoverings
·
Close dedup-specs audit: 0.17% duplication (5/3000) — catalo a08ffaa0 →