feat(shop): collections, search, policies, PDP gallery, qty, cart drawer, discounts#833
feat(shop): collections, search, policies, PDP gallery, qty, cart drawer, discounts#833tannerlinsley merged 1 commit intomainfrom
Conversation
…t drawer, discount codes Brings the shop up to parity with a standard Shopify storefront: **New routes** - /shop/collections/$handle: collection listings with sort + cursor pagination, SSR, SEO meta, breadcrumbs - /shop/pages/$handle: renders Shopify admin-managed pages (shipping, returns, privacy, terms, about, etc.). Sidebar now links to the four standard policies out of the box. - /shop/search: Storefront API search with cursor pagination, URL-driven query param, accessible search form **Listing enhancements** - Sort dropdown on /shop and /shop/collections/* wired to URL search params (SSR-correct, shareable, back/forward friendly) - Load More cursor-based pagination on all listings (first page always comes from the loader; subsequent pages accumulate client-side) - Responsive images via a shared ProductImage primitive: srcset with 1x / 1.5x / 2x / 3x widths bounded by the image's intrinsic width, correct sizes hint, lazy-loaded past the fold, eager for the first row **PDP** - Image gallery with thumbnails; click swaps the active image, selected variant auto-focuses its own image - Quantity stepper integrated into Add to cart - Variant availability awareness: option buttons for combinations that don't resolve to an available variant get a line-through + dimmed treatment (clicks still allowed to surface the sold-out state) - JSON-LD schema.org Product block for rich search results (single offer or AggregateOffer based on variant count) - Per-product OG image via Shopify CDN transforms (1200x630 jpg, center crop) so social shares get the product photo, not the generic card - Breadcrumbs: Shop > <product> **Cart** - Discount code form in the summary panel (applyDiscountCode / removeDiscountCode server fns with valibot validation + invalid-code detection, since Shopify silently drops unknown codes) - Slide-in cart drawer (Radix Dialog) controlled by a zustand store so any component can trigger it. Add to cart on the PDP now opens the drawer on success for instant feedback without losing the PDP scroll - Navbar cart button switched from Link to drawer trigger; visibility rules unchanged (always on /shop/*, site-wide when cart has items) - Cart page gains breadcrumbs + discount code UI **Shared components** - src/components/shop/ProductCard (with compare-at-price strike-through and "from $X" when variants span a price range) - src/components/shop/ProductImage (responsive srcset via Shopify CDN transforms, pure HTML — no hydrogen-react Provider needed) - src/components/shop/Breadcrumbs (accessible nav with aria-current) - src/components/shop/CartDrawer - src/components/shop/cartDrawerStore (zustand) **Queries** - Shared ProductCard GraphQL fragment reused across products list, collection products, and search results - New: COLLECTION_QUERY, PAGE_QUERY, SEARCH_QUERY, CART_DISCOUNT_CODES_UPDATE_MUTATION - Cart fragment now includes discountCodes - Products query now takes cursor + sort args **Sidebar** - Adds Search link, Info section (Shipping/Returns/Privacy/Terms) - Sidebar renders Shopify Collections live via the parent /shop loader Nothing here requires new env vars. Policy pages render whatever Shopify's admin has configured under Online Store > Pages with matching handles; a missing page falls through to the existing 404.
✅ Deploy Preview for tanstack ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR implements a comprehensive shopping experience overhaul, introducing search and collection browsing routes, a global cart drawer with discount code management, new product display components, API pagination and sorting support, and enhanced product detail pages with image galleries and variant selectors. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |

Summary
Brings the shop to Shopify-theme parity. Everything on the "standard storefront" checklist that was missing after the initial ship is now in.
New routes
/shop/collections/$handle— collection listings with sort + Load More pagination, SEO meta, breadcrumbs/shop/pages/$handle— renders Shopify-admin-managed pages (policies, about, etc.)/shop/search— Storefront API search with paginated resultsListings
/shopand each collection (URL-driven; default sort uses a clean URL)ProductImageprimitive (srcset 1x/1.5x/2x/3x via Shopify CDN transforms, correct sizes hint, lazy past the fold)PDP
Product/AggregateOfferschema for rich search resultsCart
applicableand surfaces a user-facing error)/shop/*, site-wide when cart has items)Sidebar
/shoploaderNew shared components under
src/components/shop/ProductCard(handles "from $X" ranges + compare-at strike-through)ProductImage(srcset, no hydrogen-react Provider needed)BreadcrumbsCartDrawercartDrawerStore(zustand)Queries
ProductCardGraphQL fragment for products/collection/searchCOLLECTION_QUERY,PAGE_QUERY,SEARCH_QUERY,CART_DISCOUNT_CODES_UPDATE_MUTATIONdiscountCodesEnv / infra
shipping-policy,refund-policy,privacy-policy,terms-of-serviceto populate the sidebar Info links — missing pages fall through to the existing 404.Test plan
/shop?sort=PRICEorders products ascending by price; default URL stays clean/shop/collections/<handle>renders with the collection's products and sort works/shop/search?q=...returns results; empty query shows the prompt, no matches shows the "No products match" state/shop/*route from the navbar cart button, and from non-shop routes when the cart has items<script type="application/ld+json">present with valid schema.org Product/shop/pages/shipping-policyetc.) 404 gracefully until pages are created in Shopify adminSummary by CodeRabbit