PEARLYjams — Shopify Storefront Redesign (Global + Korea)
Redesigned and shipped both storefronts for PEARLYjams, a Korean family matching-sleepwear brand — a USD global store and a bilingual KO/EN Korean store — across four contracted phases, all delivered live between 21 July and 14 August 2026. Every theme change was deployed through the Shopify admin API, because the client's least-privilege collaborator scope would not open the theme code editor.
The problem
PEARLYjams sold one print across the whole family — women, men, kids, baby, pet, plus plush companions — but the storefront gave shoppers no way to find any of it. The homepage was a repeating wall of print blocks, there was no category navigation, and the underlying product data could not support one: `product_type` was empty on every product, the Shopify taxonomy Category was wrong (a nightgown filed as "Shorts"), `Vendor` was inconsistent, and no tags existed at all. Three collections were live with zero products and no conditions, and one shipped with "Lorem Ipsum" in its description. On top of that, the brand ran two entirely separate Shopify stores — a USD global store and a KRW Korean store where the primary language is Korean — so nothing built on one carried to the other. Access was deliberately least-privilege (Online Store + Products + Content), which meant no metafield definitions, no store settings, and a theme code editor that rendered blank.
The solution
Built the whole information architecture off the two fields that were actually trustworthy — product title and the product-level `Color` metafield — then layered navigation, design, and product-page work on top of it, publishing each phase only after the client approved a preview. When the theme editor UI refused to load under the collaborator scope, deployment moved to the admin's own `assets.json` REST endpoint (session cookie + `x-csrf-token`, PUTs issued from inside an admin page) with `themePublish`/`themeDuplicate` over GraphQL, which turned the whole theme into a scriptable, diffable, rollback-able target. The Korean store was rebuilt as a true mirror — 28 new collections, 12 uploaded images, patched theme assets, and a full KO/EN translation pass registered through `translationsRegister`.
Overview
PEARLYjams is a family matching-sleepwear brand in Incheon selling one print across women, men, kids, baby, pet, and plush companions. They ran two completely separate Shopify stores — `pearly-jams-usa` (USD, pearlyjams.com) and `pearly-jams-kr` (KRW, Korean-primary with an English locale, pearlyjams.kr) — on a Maestrooo Prestige 10.9.2 theme maintained by an outside agency. I took the work on a direct fixed-price contract dated 22 July 2026: four milestones, each paid upfront. All four shipped live. Phase 1 (mega-menu navigation and smart filters) completed 28 July, Phase 2 (homepage and collection pages) published 4 August, Phase 3 (product pages and launch polish) published 5 August, and the full Korean mirror went live 14 August.
The interesting constraint was access. The client granted least-privilege collaborator scope on purpose — Online Store, Products, Content, nothing else — which blocks metafield *definitions* and, in practice, renders the theme code editor as a blank page. Rather than ask for broader permissions, I moved deployment onto the admin's own APIs: `GET/PUT admin.shopify.com/store/.../themes/{id}/assets.json` authenticated with the session cookie and the page's `csrfToken`, with `themePublish` and theme creation driven over GraphQL. That produced a repeatable pipeline — duplicate live theme into an unlinked draft, patch, QA, publish, keep the previous theme unpublished as an explicit rollback point. Duplicating a theme meant programmatically copying 224 assets in batches; the `.ttf` fonts silently failed as `value` and `src` and only transferred as base64 `attachment`, a bug caught by a pre-publish audit that found both fonts 404ing on the draft before it reached shoppers.
The data work came first because none of the navigation would hold without it. Collections were rebuilt from `Title contains` rules and the `Color` metafield rather than the broken taxonomy, three empty collections were repaired to 11 products each, and four mis-scoped or orphaned products were found by diffing live `products.json` against variant colors and product imagery. I populated the `shopify.fabric` metafield across the catalog and added a Fabric facet in Search & Discovery on both stores. Each store ended at 46 collections with zero empties and product counts matching 1:1 — a discrepancy that only closed after normalizing handles containing `™` and rewriting a Korean smart rule whose title condition ("Pocket T-Shirt Set" vs "Men's Pocket T-Shirt Set") silently matched nothing. On the front end I wrote custom theme layers: an IntersectionObserver scroll-reveal and Ken Burns motion pass that honors `prefers-reduced-motion`, a mobile sticky add-to-cart, a product gallery with a color rail, a dark footer delivered inline to sidestep CDN cache lag, a two-column mobile product grid, and an accessibility script that zeroed out missing `alt` attributes.
Before committing to a visual direction I built the two candidate homepages as a Next.js 15 / React 19 / TypeScript site with an A/B switcher and deployed it to Vercel, so the client compared live pages instead of static mockups — they picked Direction A, which is what shipped. The Korean mirror surfaced the failure mode worth remembering: theme duplication does not carry translations (`translatableResources` returned 8 resources for the live theme and 0 for the copy), so the English storefront would have gone out fully Korean. Fixing it exposed a second trap — mega-menu blocks bind to menu items *by name*, so translating the menu silently dropped the English mega-menu from 16 elements to zero — and a third, where the sticky add-to-cart matched button text against `/add to cart/i` and never fired against `장바구니 담기`. Final QA ran at 390px across both languages: exactly one `h1` per page, no locale-prefix-less links, 53/53 internal links and 46/46 collection pages returning 200, and zero JS or network errors. The engagement has since continued past the original contract into Naver Smart Store listing work.
Key features
- Mega-menu navigation with 6 top-level sections and 21 sub-links, built twice (global + Korean) because Shopify menus do not transfer between stores
- Smart collections driven by title rules and the product-level Color metafield after the Shopify taxonomy Category field proved unreliable
- Custom Fabric facet: shopify.fabric metafield populated across the catalog and wired into Search & Discovery on both stores
- Theme deployment through the Shopify admin assets.json REST endpoint (session + CSRF) with GraphQL themePublish, working around a collaborator scope that will not open the theme code editor
- Programmatic theme duplication — 224 assets copied in batches, with binary fonts transferred as base64 attachment
- Custom motion layer: IntersectionObserver scroll-reveal, Ken Burns hero, card hover lift/zoom, glass sticky header, full prefers-reduced-motion support
- Mobile-first product page: sticky add-to-cart, filtered image gallery, color rail, trust block, two-column product grid
- Full KO/EN bilingual mirror — 28 collections created, translations registered via translationsRegister, mega-menu bindings translated in both directions
- Next.js concept site with an A/B direction switcher deployed to Vercel so the client approved a live page, not a static mockup
- Phased publish with an explicit rollback point: previous live theme kept unpublished after every launch