From c838f404405aa239480808416485e18db7939bed Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sat, 25 Jan 2025 10:49:05 +0000 Subject: [PATCH] feat: Support youtube list embed URL (#4786) ## Description With this PR user can paste an embed url like this https://youtube.com/embed?listType=playlist&list=UUjk2nKmHzgH5Xy-C5qYRd5A and we will still be able to render it ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 0000) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env` file --- packages/sdk-components-react/src/youtube.tsx | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/sdk-components-react/src/youtube.tsx b/packages/sdk-components-react/src/youtube.tsx index 145303b4ef41..e8fc6119a1f1 100644 --- a/packages/sdk-components-react/src/youtube.tsx +++ b/packages/sdk-components-react/src/youtube.tsx @@ -173,6 +173,11 @@ const getVideoId = (url?: string) => { } try { const urlObj = new URL(url); + // It's already an embed URL, we don't need to extract video id. + // It could be something like this https://youtube.com/embed?listType=playlist&list=UUjk2nKmHzgH5Xy-C5qYRd5A + if (urlObj.pathname === "/embed") { + return; + } if (urlObj.hostname === "youtu.be") { return urlObj.pathname.slice(1); } @@ -185,12 +190,23 @@ const getVideoId = (url?: string) => { const getVideoUrl = (options: YouTubePlayerOptions, videoUrlOrigin: string) => { const videoId = getVideoId(options.url); - if (!videoId) { - return; + const url = new URL(videoUrlOrigin); + + if (videoId) { + url.pathname = `/embed/${videoId}`; + } else if (options.url) { + // E.g. this won't have videoId https://youtube.com/embed?listType=playlist&list=UUjk2nKmHzgH5Xy-C5qYRd5A + // It may also contain parameters since its an embed URL, so we want to keep it as-is and just use the origin we predefined + // so that no cookies option still works + try { + const parsedUrl = new URL(options.url); + url.pathname = parsedUrl.pathname; + url.search = parsedUrl.search; + } catch { + // Ignore invalid URL + } } - const url = new URL(`${videoUrlOrigin}/embed/${videoId}`); - const optionsKeys = Object.keys(options) as (keyof YouTubePlayerParameters)[]; const parameters: Record = {};