diff --git a/src/pages/blog/[slug].jsx b/src/pages/blog/[slug].jsx index 1c2fef7f..fab01ac0 100644 --- a/src/pages/blog/[slug].jsx +++ b/src/pages/blog/[slug].jsx @@ -69,6 +69,7 @@ SinglePost.query = gql` name id: clientId parentId: parentClientId + renderedHtml ...${blocks.CoreParagraph.fragments.key} ...${blocks.CoreColumns.fragments.key} ...${blocks.CoreColumn.fragments.key} @@ -81,6 +82,7 @@ SinglePost.query = gql` ...${blocks.CoreList.fragments.key} ...${blocks.CoreHeading.fragments.key} ...${blocks.CoreCode.fragments.key} + ...${blocks.CoreEmbed.fragments.key} } } } @@ -96,6 +98,7 @@ SinglePost.query = gql` ${blocks.CoreList.fragments.entry} ${blocks.CoreHeading.fragments.entry} ${blocks.CoreCode.fragments.entry} + ${blocks.CoreEmbed.fragments.entry} `; SinglePost.variables = ({ params }) => ({ slug: params.slug }); diff --git a/src/wp-blocks/core-embed.jsx b/src/wp-blocks/core-embed.jsx new file mode 100644 index 00000000..5a8d1722 --- /dev/null +++ b/src/wp-blocks/core-embed.jsx @@ -0,0 +1,100 @@ +import { gql } from "@apollo/client"; + +/** + * Extracts a YouTube video ID from any of the common URL shapes: + * - https://www.youtube.com/watch?v=ID + * - https://youtu.be/ID + * - https://www.youtube.com/embed/ID + * - https://www.youtube.com/shorts/ID + */ +function getYouTubeId(url) { + if (!url) return; + try { + // eslint-disable-next-line n/prefer-global/url + const parsed = new URL(url); + const host = parsed.hostname.replace(/^www\./, ""); + if (host === "youtu.be") { + return parsed.pathname.slice(1).split("/")[0] || undefined; + } + + if (host.endsWith("youtube.com") || host.endsWith("youtube-nocookie.com")) { + if (parsed.pathname === "/watch") { + return parsed.searchParams.get("v"); + } + + const match = parsed.pathname.match( + /^\/(?:embed|shorts|v)\/(?[^/?#]+)/, + ); + if (match) return match.groups?.id; + } + } catch { + // Fall through to regex below + } + + const fallback = url.match( + /(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/|v\/)|youtu\.be\/)(?[\w-]{11})/, + ); + return fallback ? fallback.groups?.id : undefined; +} + +export default function CoreEmbed(props) { + const { attributes, renderedHtml } = props; + const { url, providerNameSlug, caption, className } = attributes ?? {}; + + if (providerNameSlug === "youtube" || /youtu\.?be/i.test(url ?? "")) { + const videoId = getYouTubeId(url); + if (videoId) { + return ( +
+
+ {/* eslint-disable-next-line react/iframe-missing-sandbox */} +