Skip to content

feat(next-ui): add YoutubeEmbed component#2627

Merged
paales merged 6 commits into
canaryfrom
feat/youtube-embed
May 20, 2026
Merged

feat(next-ui): add YoutubeEmbed component#2627
paales merged 6 commits into
canaryfrom
feat/youtube-embed

Conversation

@paales
Copy link
Copy Markdown
Member

@paales paales commented May 20, 2026

Summary

  • Add a new YoutubeEmbed component to @graphcommerce/next-ui — a lightweight, lazy-loaded YouTube player that defers iframe creation until the user clicks the poster.
  • Self-contained MUI Box + sx styling, no external CSS file to import.
  • React 19 ref-as-prop pattern, supports playlists, no-cookie mode, custom aspect ratios, and ad-network preconnect hints.

Ported from the unfinished feature/todo-list-paul branch. The original component depended on external react-lite-youtube-embed CSS classes; this version is styled entirely with MUI so consumers can drop it in without extra wiring.

Usage

import { YoutubeEmbed } from '@graphcommerce/next-ui'

<YoutubeEmbed id='dQw4w9WgXcQ' title='Demo video' />

Test plan

  • npx --package=@typescript/native-preview tsgo --noEmit -p . from examples/magento-graphcms passes (no new type errors)
  • yarn test from the repo root passes (all 11 vitest files, 56 tests)
  • Smoke-test in a real example page: render with a YouTube id, click the poster, confirm the iframe loads and plays

🤖 Generated with Claude Code

Lightweight lazy-loaded YouTube player that defers iframe creation until
the user clicks the poster. Uses preconnect on hover for fast playback
start and is styled entirely with MUI sx, so no external CSS is required.

Ported from the unfinished `feature/todo-list-paul` branch and modernised:
- styling moved from external `react-lite-youtube-embed` CSS classes to
  MUI `Box` + `sx`, so the component works out of the box
- React 19 ref-as-prop pattern (no `forwardRef`)
- supports playlists, no-cookie mode, custom aspect ratios, and
  ad-network preconnect hints
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
graphcommerce-246 Ready Ready Preview May 20, 2026 1:24pm
graphcommerce-247 Ready Ready Preview May 20, 2026 1:24pm
graphcommerce-hygraph-dynamic-rows-ui Ready Ready Preview May 20, 2026 1:24pm
graphcommerce-open-source Ready Ready Preview May 20, 2026 1:24pm
graphcommerce-storyblok Ready Ready Preview May 20, 2026 1:24pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 20, 2026

🦋 Changeset detected

Latest commit: 45b3c66

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 86 packages
Name Type
@graphcommerce/next-ui Major
@graphcommerce/magento-product Major
@graphcommerce/misc Major
@graphcommerce/address-fields-nl Major
@graphcommerce/algolia-categories Major
@graphcommerce/algolia-insights Major
@graphcommerce/algolia-personalization Major
@graphcommerce/algolia-products Major
@graphcommerce/algolia-recommend Major
@graphcommerce/algolia-search Major
@graphcommerce/demo-magento-graphcommerce Major
@graphcommerce/ecommerce-ui Major
@graphcommerce/google-datalayer Major
@graphcommerce/google-playstore Major
@graphcommerce/googleanalytics Major
@graphcommerce/googlerecaptcha Major
@graphcommerce/googletagmanager Major
@graphcommerce/hygraph-dynamic-rows Major
@graphcommerce/hygraph-ui Major
@graphcommerce/lingui-next Major
@graphcommerce/magento-cart-checkout Major
@graphcommerce/magento-cart-coupon Major
@graphcommerce/magento-cart-email Major
@graphcommerce/magento-cart-items Major
@graphcommerce/magento-cart-payment-method Major
@graphcommerce/magento-cart-pickup Major
@graphcommerce/magento-cart-shipping-address Major
@graphcommerce/magento-cart-shipping-method Major
@graphcommerce/magento-cart Major
@graphcommerce/magento-category Major
@graphcommerce/magento-compare Major
@graphcommerce/magento-customer Major
@graphcommerce/magento-graphql-rest Major
@graphcommerce/magento-newsletter Major
@graphcommerce/magento-payment-adyen Major
@graphcommerce/magento-payment-afterpay Major
@graphcommerce/magento-payment-braintree Major
@graphcommerce/magento-payment-included Major
@graphcommerce/magento-payment-klarna Major
@graphcommerce/magento-payment-multisafepay Major
@graphcommerce/magento-payment-paypal Major
@graphcommerce/magento-payment-tokens Major
@graphcommerce/magento-product-bundle Major
@graphcommerce/magento-product-configurable Major
@graphcommerce/magento-product-downloadable Major
@graphcommerce/magento-product-grouped Major
@graphcommerce/magento-product-simple Major
@graphcommerce/magento-product-virtual Major
@graphcommerce/magento-recently-viewed-products Major
@graphcommerce/magento-review Major
@graphcommerce/magento-search-overlay Major
@graphcommerce/magento-search Major
@graphcommerce/magento-store Major
@graphcommerce/magento-wishlist Major
@graphcommerce/mollie-magento-payment Major
@graphcommerce/storyblok-ui Major
@graphcommerce/framer-next-pages-example Major
@graphcommerce/framer-scroller-example Major
@graphcommerce/magento-graphcms Major
@graphcommerce/magento-open-source Major
@graphcommerce/magento-storyblok Major
@graphcommerce/graphcms-ui Major
@graphcommerce/magento-cms Major
@graphcommerce/docs Major
@graphcommerce/browserslist-config-pwa Major
@graphcommerce/changeset-changelog Major
@graphcommerce/eslint-config-pwa Major
@graphcommerce/graphql-codegen-markdown-docs Major
@graphcommerce/graphql-codegen-near-operation-file Major
@graphcommerce/graphql-codegen-relay-optimizer-plugin Major
@graphcommerce/next-config Major
@graphcommerce/prettier-config-pwa Major
@graphcommerce/typescript-config-pwa Major
@graphcommerce/cli Major
@graphcommerce/framer-next-pages Major
@graphcommerce/framer-scroller Major
@graphcommerce/framer-utils Major
@graphcommerce/graphql-mesh Major
@graphcommerce/graphql Major
@graphcommerce/hygraph-cli Major
@graphcommerce/hygraph-dynamic-rows-ui Major
@graphcommerce/image Major
@graphcommerce/magento-graphql Major
@graphcommerce/react-hook-form Major
@graphcommerce/service-worker Major
@graphcommerce/image-example Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

paales added 2 commits May 20, 2026 14:32
Add `copy/pages/test/youtube-embed.tsx` that demonstrates the new
`YoutubeEmbed` component in four configurations:

- default 16:9
- custom 1:1 aspect
- playlist with `cookie` (youtube.com instead of youtube-nocookie.com)
- muted with `maxresdefault` poster

Link from the `/test` overview page so the demo is discoverable.
`ProductVideo` (rendered by `ProductPageGallery`) previously embedded
YouTube videos with a plain `<iframe>` that loaded only after the user
clicked the play overlay. Switch the YouTube path to the new
`YoutubeEmbed` component from next-ui, which preconnects to YouTube on
hover and lazy-loads the iframe on click. Vimeo and self-hosted video
paths are unchanged.

The Magento media-gallery preview image is forwarded as the
`thumbnail` prop, so the poster the user sees before playback stays
consistent with the rest of the product gallery (no jump to a
YouTube-generated thumbnail).

Replaces the throwaway `demo-magento-graphcommerce/copy/pages/test/youtube-embed.tsx`
demo route — a feature lands in the example storefronts by wiring it
into an existing flow (here: product page → media gallery → YouTube
entry), not by adding a separate test route.
paales added 2 commits May 20, 2026 15:20
`SidebarGallery` was spreading only `src`, `width`, `height`, `loading`,
`sx`, `sizes`, and `alt` onto each `MotionImageAspect`. The `Additional`
component and `slotProps` set by `ProductPageGallery` for video entries
were silently dropped, so `<ProductVideo>` (and now `<YoutubeEmbed>`)
never reached the DOM — every gallery video slide rendered as a static
image with no play button at all.

Spread the full `image` props onto `MotionImageAspect` instead, and
merge `image.sx` into the gallery's default `{ display: 'block',
objectFit: 'contain' }` via `sxx` so the per-image `objectFit: 'cover'`
that ProductPageGallery sets for non-image slides also takes effect.

Also: fix playwright.config.ts so `npx playwright test` actually loads.
The previous config imported `examples/magento-graphcms/next.config.ts`,
which transitively pulls `@graphcommerce/next-config`'s ESM build into
a CJS context and crashes Playwright's TS loader with
`ReferenceError: exports is not defined in ES module scope`. The
import was only used to read i18n locales for multi-locale project
generation; replace it with an opt-in `PLAYWRIGHT_LOCALES=nl,de` env
var so the default config no longer touches Next.js internals.

Add the first playwright test for this PR's showcase:
`packages/magento-product/test/youtubeEmbedInGallery.playwright.ts`
navigates to a product with a YouTube video in its media gallery,
asserts that `YoutubeEmbed-root` is present, that the poster comes
from the Magento preview image (not `i.ytimg.com`), that hovering
adds the `<link rel="preconnect">` to YouTube, and that clicking
swaps in the iframe with the expected video id and `autoplay=1`.
`PRODUCT_URL` and `EXPECTED_YOUTUBE_ID` env vars override the
backend-specific defaults.
`npx playwright test` writes `test-results/.last-run.json` (and a full
`playwright-report/` on failures) next to the runner. These are local
artifacts, not source — exclude them from git.
@paales
Copy link
Copy Markdown
Member Author

paales commented May 20, 2026

poster

@paales paales merged commit 1cb27a9 into canary May 20, 2026
6 of 7 checks passed
@paales paales deleted the feat/youtube-embed branch May 20, 2026 15:11
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