[object Object]

← back to Designer Wallcoverings

pending-approval: grid.js init-abort root cause + gated live-push memo

828034b5f91d8343aa43d7e98e6f41fe9d68b158 · 2026-06-23 09:36:49 -0700 · Steve Studio

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 828034b5f91d8343aa43d7e98e6f41fe9d68b158
Author: Steve Studio <steve@designerwallcoverings.com>
Date:   Tue Jun 23 09:36:49 2026 -0700

    pending-approval: grid.js init-abort root cause + gated live-push memo
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 .../grid-js-init-abort-and-dev-build.md            | 139 +++++++++++++++++++++
 1 file changed, 139 insertions(+)

diff --git a/pending-approval/grid-js-init-abort-and-dev-build.md b/pending-approval/grid-js-init-abort-and-dev-build.md
new file mode 100644
index 00000000..12b3d311
--- /dev/null
+++ b/pending-approval/grid-js-init-abort-and-dev-build.md
@@ -0,0 +1,139 @@
+# grid.js init-abort + shipped DEV build — root cause, staged fix, gated live push
+
+**Owner:** vp-dw-commerce · **Drafted:** 2026-06-23 · **Status:** root-caused; fix STAGED on dev theme; LIVE push + final visual confirm AWAITING STEVE
+**Gate reason:** live customer-facing theme-asset writes (grid.js + 2 Liquid files) on the published theme.
+**Live theme (verified, role==main):** **142250278963 "Steves Version 5.0"** (Out of the Sandbox "Grid" v7.1.0).
+**Dev theme used for staging:** **143947038771 "★ 5.0 Grid+Infinite FIX (approve)"** (same theme the parallel `collection-grid-toolbar-and-image-perf.md` memo named as the consolidation base).
+
+> **Read this WITH `pending-approval/collection-grid-toolbar-and-image-perf.md`.** That memo
+> correctly attributes the *Boost-app* collection grid's oversized images to the Boost SD admin
+> image-size setting. THIS memo covers a **separate, deeper defect** that the Boost finding does
+> NOT explain: the theme's own `grid.js` JavaScript bundle **crashes on init and aborts before any
+> theme-managed grid/carousel lays out** — which is why the homepage featured-collection carousels
+> and the OOTS-native (non-Boost) product cards render full-width/native-size. Both fixes are
+> needed; they don't conflict.
+
+---
+
+## 1. Confirmed root cause (live-DOM forensics + reading the readable production bundle)
+
+The theme's `grid.js` registers all section behaviors through a `ShopifySectionsManager`. On the
+live markup, **two section constructors throw because DW's custom Liquid removed DOM hooks the
+Out-of-the-Sandbox section classes dereference with NO null-guard.** The throw propagates out of
+`ShopifySectionsManager._initSections`, which **aborts the whole init loop — so NO section after the
+throw initializes**, including the product-grid carousels/masonry. Result: `window.Flickity`
+undefined, `.flickity-enabled` = 0, and theme-managed grids fall back to `display:block`, sizing
+cards to the image's intrinsic width = the "giant blown-out images."
+
+**Throw #1 — `StaticHeader._setSearchWidth` (header):**
+```
+TypeError: Cannot read properties of null (reading 'style')
+  at StaticHeader._setSearchWidth (grid.js)   // this.headerSearch.style.width = ...
+  at new StaticHeader → ShopifySectionsManager._createInstance → _initSections
+```
+The OOTS `StaticHeader` queries `[data-header-search]`, `[data-header-search-button]`,
+`[data-header-search-button-close]`. DW's custom header (`.header-search-inline` + `.search-takeover`
++ `data-header-search-toggle`) **replaced the original search form and removed all three hooks**
+(verified: 0 of each in live `sections/header.liquid` and `snippets/search-form.liquid`).
+`this.headerSearch` is null → constructor throws → manager aborts.
+
+**Throw #2 — `ProductListItem` constructor (collection cards):**
+```
+TypeError: Cannot read properties of null (reading 'dataset')
+  at new ProductListItem (grid.js)   // this.el.closest('[data-product-hover]').dataset.productHover
+  at new StaticCollection → _initSections
+```
+The per-card `[data-product-hover]` wrapper was dropped from `snippets/product-list-item.liquid`
+(only the section-level one remained: live DOM showed `[data-product-hover]` = 1 vs 8 cards).
+`.closest(...)` returns null → `.dataset` throws.
+
+**Independent defect (asset hygiene): the live `grid.js` is a webpack `eval-source-map` DEV build.**
+2,022,084 bytes, 89 `eval()` calls, opens with the webpack "ATTENTION: …neither made for production…"
+banner. The correct production build is 554,793 bytes, 0 evals, readable stack traces. The dev build
+has propagated to every theme touched since ~2026-02-12. **Both builds crash identically on the
+broken markup** — so the dev-build is NOT the cause of the init crash, but it is ~3.6× the bytes,
+un-debuggable in prod, and not a production artifact. (The readable production build is exactly what
+let me capture the stack traces above.)
+
+## 2. Where the good production grid.js came from
+
+Last-known-good production `grid.js` recovered from an **older unpublished theme version still in the
+store: `141318651955` "Variant discount issue fix | 2/6/26" (2026-02-05)** — the only theme of 15 not
+yet poisoned by the dev build. Pulled via the Admin asset API, validated: `node --check` passes, 0
+evals, self-inits via the webpack bootstrap IIFE, SAME entry module `./source/scripts/grid.js` as the
+current build, contains Flickity + Masonry + the `flickity-enabled` class. Saved at
+`shopify/grid-js-fix/grid.js.production-554k.from-theme-141318651955`.
+*(DTD panel 3/3 chose "restore last-known-good prod build" over "rebuild webpack from the eval modules.")*
+
+## 3. What is STAGED on dev theme 143947038771 (reversible; no live change)
+
+| Asset | Change | Backup |
+|---|---|---|
+| `assets/grid.js` | dev eval-source-map build → 554KB production build | `shopify/grid-js-fix/backups/grid.js.dev-143947038771.before` |
+| `snippets/product-list-item.liquid` | added `data-product-hover="{{ product_hover }}"` to the `<article>` | `…/backups/product-list-item.liquid.live-142250278963.before` |
+| `sections/header.liquid` | added a visually-hidden, inert `.header-search` shim carrying `[data-header-search]` + `[data-header-search-button]` + `[-close]` (display:none, off-screen, `tabindex=-1`, `aria-hidden`) so `StaticHeader` constructs without throwing — ZERO visible UX change | `…/backups/header.liquid.live-142250278963.before` |
+
+Patched copies live at `shopify/grid-js-fix/patched/`. The staged dev grid.js verified server-side:
+0 evals, 554,793 bytes, `flickity-enabled` string present.
+
+## 4. What is PROVEN vs what Steve must confirm (honest scope)
+
+**PROVEN (offline + asset API):**
+- The exact throw sites + null elements (stack traces + live-DOM hook counts).
+- After the patches, the init-aborting `StaticHeader`/`ProductListItem`/`_initSections` throws are
+  GONE (no longer raised), and per-card `data-product-hover` + the header hooks are present.
+- Collection cards that ARE inside `.collection-products[data-collection-grid]` render correctly
+  (CSS grid, ~77–103px). The blown-up cards are the ones in the bare `section.collection > div`
+  (`display:block`) that the theme-managed grid never laid out.
+- The 554KB production build is valid, self-initing, same source/entry as live.
+
+**NOT yet visually confirmed (requires the authenticated admin "Preview"):** that Flickity/Masonry
+then actually engages and the homepage carousels + the non-Boost cards render constrained. An
+offline route-swap CANNOT fully reproduce the Shopify theme runtime (Boost SD app, section JSON,
+Flickity CSS/lifecycle), so I am **not** claiming the visual fix as verified. This is the one step
+only Steve can do cleanly (the preview session comes from the admin Preview button).
+
+## 5. Steve — verify on dev, THEN approve the live push
+
+**Step A — open the dev preview (authenticated):** Shopify admin → Online Store → Themes →
+"★ 5.0 Grid+Infinite FIX (approve)" (143947038771) → **Preview**. Open the homepage and a collection,
+e.g. `/collections/acoustical?pf_t_product_type=Wallcovering&pf_t_color=Green`.
+
+**Step B — paste this in the browser console on the preview to confirm init:**
+```js
+console.log({
+  Flickity: typeof window.Flickity,
+  flickityEnabled: document.querySelectorAll('.flickity-enabled').length,
+  blownCards: [...document.querySelectorAll('.product-list-item img')]
+                .filter(i => i.getBoundingClientRect().width > 700).length
+});
+// WANT: Flickity !== 'undefined' (on home), flickityEnabled > 0, blownCards === 0
+```
+If `blownCards === 0` and the homepage carousels render as carousels, the fix is good.
+
+**Step C — if it looks right, paste to approve the LIVE push.** I will then apply the SAME three
+assets to live theme **142250278963** (backups already captured), 90s apart, and re-verify on the
+live URL. Exact commands I will run (theme token via `/secrets` `SHOPIFY_THEME_TOKEN`, never hardcoded):
+```bash
+TOKEN=$(grep '^SHOPIFY_THEME_TOKEN=' ~/Projects/secrets-manager/.env | cut -d= -f2)
+LIVE=142250278963
+# 1) grid.js (production build)
+curl -s -X PUT "https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/themes/$LIVE/assets.json" \
+  -H "X-Shopify-Access-Token: $TOKEN" -H 'Content-Type: application/json' \
+  --data-binary @<(python3 -c "import json;print(json.dumps({'asset':{'key':'assets/grid.js','value':open('$HOME/Projects/Designer-Wallcoverings/shopify/grid-js-fix/grid.js.production-554k.from-theme-141318651955').read()}}))")
+# 2) snippets/product-list-item.liquid   3) sections/header.liquid  (same pattern, from shopify/grid-js-fix/patched/)
+```
+
+## 6. Watch-item (not blocking this fix)
+- The **homepage featured-collection sections currently contain only ONE product each**; with the
+  carousel restored a 1-item section should still size correctly, but confirm the "BRAND MCKENZIE UK"
+  section specifically in Step A. If a single-item section still looks off after the fix, that is a
+  CSS/section-config follow-up, separate from this init-abort fix.
+- This fix is **complementary to** the Boost SD image-size admin setting in
+  `collection-grid-toolbar-and-image-perf.md` item 3 — do both.
+
+## Steve, paste to proceed
+- [ ] I confirmed the dev preview (Step A/B): Flickity engages + no blown cards → **approve LIVE push of all 3 assets to 142250278963**
+- [ ] OR: dev preview still shows blown cards → keep digging (I'll escalate to rebuilding the bundle / the single-item CSS path)
+
+**$ cost:** $0 (local Playwright + read-only public pages + read/write theme API to the UNPUBLISHED dev theme only; the 2 DTD panels used local Qwen + ~$0.02–0.05 Codex each ≈ **$0.04–0.10 total**).

← e78be974 auto-save: 2026-06-23T09:20:41 (16 files) — shopify/scripts/  ·  back to Designer Wallcoverings  ·  audit: DW microsites infinite scroll status — 3 converted, 3 3d582696 →