← back to Designer Wallcoverings

pending-approval/tile-images-fix-2026-08-07/DEPLOY-RUNBOOK.md

42 lines

# Deploy runbook — permanent cure for the 4 category-Page tile grids

Steve chose: **grant content scope once**, then Claude ships headless.
Theme token (...2954) already has write_theme_code/read_themes/write_themes.
Admin token (...75b9) has products/inventory/publications only — NO content, NO themes.

## STEP 1 (Steve, ~1 min): grant content scope
Shopify Admin → Settings → Apps and sales channels → **Develop apps** →
open the app behind the admin API token (the custom app) → **Configuration** →
Admin API access scopes → add **`write_content`** and **`read_content`** → Save →
**Install / Update** the app → copy the (possibly rotated) Admin API access token →
paste it to Claude (routes via the `secrets` skill as SHOPIFY_ADMIN_TOKEN).

## STEP 2 (Claude, headless once token lands)
1. GET raw body_html for each of the 4 pages (authoritative source — no scraping):
   `/admin/api/2024-10/pages.json?handle=<h>` → page.id + body_html.
2. Parse the REAL curated tile list from body_html (clean `<img src>`, no lazy-load
   placeholders, no data-URIs) → ordered [{link,label}] per page.
3. Rebuild page.<suffix>.liquid: page CSS + dynamic grid where each tile image =
   collection.image -> first product image -> verified static fallback -> JS guard.
4. Deploy the 4 templates to a DUPLICATE **preview theme** (theme token) first.
5. Bind pages to templates on the preview theme path / set template_suffix, verify
   each page renders + HEAD-probe every tile image = 200 + eyeball. Iterate if needed.
6. Flip live: set page.template_suffix on the 4 pages (content token). Re-verify live.
   Rollback = clear template_suffix (one call) — instant revert to current body_html.
7. Fold in mislabel rulings (Mica x2, Lincrusta, Jute, Linen repointed).
8. Add a canary (dw-tile-image-canary) that HEAD-probes these grids weekly so a
   future image churn is caught in a day, not by a customer.

## Why this is the cure, not a patch
Current pages hardcode CDN URLs in body_html -> rot on every image re-upload
(~42% dead today, 185/443). Dynamic templates read the live collection image at
page load -> cannot rot. Dead-link/empty-collection tiles self-handle via the
fallback chain + guard.

## Artifacts in this folder
- README.md ................ findings + full broken/mislabel breakdown
- audit-full.json .......... every tile, every page, HEAD/GET status
- replacement-swaps.json ... 166 verified-live replacements + 19 unresolved (dead/empty)
- error-guard.html ......... capture-phase graceful-degrade block (in every template)
- templates-DRAFT-from-render/ . throwaway proof from rendered HTML; FINAL built from body_html