Skip to content

Add Model Viewer support for 3D product media#359

Open
hta218 wants to merge 16 commits intodevfrom
feat/model-viewer-support
Open

Add Model Viewer support for 3D product media#359
hta218 wants to merge 16 commits intodevfrom
feat/model-viewer-support

Conversation

@hta218
Copy link
Member

@hta218 hta218 commented Mar 26, 2026

Summary

  • Add ModelViewer support to render 3D product models (Model3d media type)
  • Add ExternalVideo support to render embedded YouTube/Vimeo videos
  • Add 3D cube icon badge on thumbnails and media items to indicate 3D content
  • Prevent clicking a 3D model from opening the zoom modal (interact with the model directly); zoom button still works
  • Fix source ordering so GLB is always used as src — Shopify's ModelViewer blindly picks sources[0], which can be a USDZ (ZIP) file causing a JSON parse error
  • Fix explicit sizing for <model-viewer> — it has no intrinsic dimensions and collapses without set width/height
  • Add noSwipingSelector for model-viewer in slider to prevent drag conflicts

Performance optimizations

  • Code-split ModelViewer into a lazy-loaded chunk via React.lazy() — zero bundle cost on pages without 3D models
  • loading="lazy" + reveal="interaction" for non-hero models — defer GLB fetch and GPU rendering
  • preload() hero GLB asset via react-dom for early parallel fetch
  • Add responsive sizes hints to product media images

Quickshop fix

  • Add fixedHeight prop to disable Swiper autoHeight in quickshop modal, preventing nav buttons from jumping between slides of different heights

Files changed

  • app/components/product-media/model-utils.ts — new helper that reorders sources (GLB first, USDZ as ios-src)
  • app/components/product-media/model-viewer-item.tsx — new lazy-loaded wrapper for ModelViewer
  • app/components/product-media/media-item.tsx — add MODEL_3D and EXTERNAL_VIDEO rendering with lazy loading + preload
  • app/components/product-media/media-zoom.tsx — same branches in zoom modal + cube icon on thumbnails
  • app/components/product-media/media-slider.tsx — cube icon badge, noSwipingSelector, fixedHeight support
  • app/components/product-media/media-grid.tsx — click-to-zoom guard + responsive sizes hints
  • app/components/product-media/index.tsx — thread fixedHeight prop
  • app/components/product-card/quick-shop.tsx — pass fixedHeight to ProductMedia

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant