diff --git a/package-lock.json b/package-lock.json
index 8c1023478f359c2..b7e7b03111fc61c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -91,6 +91,7 @@
"starlight-image-zoom": "0.11.1",
"starlight-links-validator": "0.14.3",
"starlight-package-managers": "0.10.0",
+ "starlight-showcases": "0.3.0",
"strip-markdown": "6.0.0",
"svgo": "3.3.2",
"tailwindcss": "3.4.17",
@@ -567,6 +568,42 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@astro-community/astro-embed-twitter": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/@astro-community/astro-embed-twitter/-/astro-embed-twitter-0.5.8.tgz",
+ "integrity": "sha512-O2ptQPw+DfipukK8czjJcTcyVgDsrs3OmrHbc3YmWRglaUTOpSTImzPo076POyNBSWjLaRKloul81DFiAMNjTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@astro-community/astro-embed-utils": "^0.1.0"
+ },
+ "peerDependencies": {
+ "astro": "^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta"
+ }
+ },
+ "node_modules/@astro-community/astro-embed-utils": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@astro-community/astro-embed-utils/-/astro-embed-utils-0.1.3.tgz",
+ "integrity": "sha512-eiMO+vfCdE9GtW6qE7X5Xl6YCKZDCoXJEWqRofQcoC3GHjqN2/WhJlnaxNVRq3demSO03UNtho57Em5p7o7AOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "linkedom": "^0.14.26"
+ }
+ },
+ "node_modules/@astro-community/astro-embed-youtube": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/@astro-community/astro-embed-youtube/-/astro-embed-youtube-0.5.6.tgz",
+ "integrity": "sha512-/mRfCl/eTBUz0kmjD1psOy0qoDDBorVp0QumUacjFcIkBullYtbeFQ2ZGZ+3N/tA6cR/OIyzr2QA4dQXlY6USg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lite-youtube-embed": "^0.3.3"
+ },
+ "peerDependencies": {
+ "astro": "^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta"
+ }
+ },
"node_modules/@astrojs/check": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.4.tgz",
@@ -7555,6 +7592,13 @@
"dev": true,
"license": "CC0-1.0"
},
+ "node_modules/cssom": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
+ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -12114,6 +12158,47 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/linkedom": {
+ "version": "0.14.26",
+ "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.26.tgz",
+ "integrity": "sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "css-select": "^5.1.0",
+ "cssom": "^0.5.0",
+ "html-escaper": "^3.0.3",
+ "htmlparser2": "^8.0.1",
+ "uhyphen": "^0.2.0"
+ }
+ },
+ "node_modules/linkedom/node_modules/htmlparser2": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "entities": "^4.4.0"
+ }
+ },
+ "node_modules/lite-youtube-embed": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/lite-youtube-embed/-/lite-youtube-embed-0.3.3.tgz",
+ "integrity": "sha512-gFfVVnj6NRjxVfJKo3qoLtpi0v5mn3AcR4eKD45wrxQuxzveFJUb+7Cr6uV6n+DjO8X3p0UzPPquhGt0H/y+NA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
"node_modules/local-pkg": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz",
@@ -16393,6 +16478,23 @@
"@astrojs/starlight": ">=0.22.0"
}
},
+ "node_modules/starlight-showcases": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/starlight-showcases/-/starlight-showcases-0.3.0.tgz",
+ "integrity": "sha512-jxKVE5IM0TZgRIni4YK1oKDh6C9pBh94oj2pKuhzg2/Cg1wjCrWy39U3i1bXkh6rL+Ly+ypQBPH3AD9cP6TLXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@astro-community/astro-embed-twitter": "^0.5.8",
+ "@astro-community/astro-embed-youtube": "^0.5.6"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@astrojs/starlight": ">=0.30.0"
+ }
+ },
"node_modules/std-env": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
@@ -17849,6 +17951,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/uhyphen": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz",
+ "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/ultrahtml": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.3.tgz",
diff --git a/package.json b/package.json
index fbe01f15b3ce6bf..67826d12399fb75 100644
--- a/package.json
+++ b/package.json
@@ -109,6 +109,7 @@
"starlight-image-zoom": "0.11.1",
"starlight-links-validator": "0.14.3",
"starlight-package-managers": "0.10.0",
+ "starlight-showcases": "0.3.0",
"strip-markdown": "6.0.0",
"svgo": "3.3.2",
"tailwindcss": "3.4.17",
diff --git a/src/components/YouTubeVideos.astro b/src/components/YouTubeVideos.astro
new file mode 100644
index 000000000000000..0394a1b04d4dcf7
--- /dev/null
+++ b/src/components/YouTubeVideos.astro
@@ -0,0 +1,31 @@
+---
+import { z } from "astro:schema";
+import { getCollection } from "astro:content";
+import { ShowcaseYouTube } from "starlight-showcases";
+
+const props = z.object({
+ products: z.string().array().default([]),
+});
+
+const { products } = props.parse(Astro.props);
+
+if (products.length === 0) {
+ const [currentSection] = Astro.url.pathname.split("/").filter(Boolean);
+ products.push(currentSection);
+}
+
+const videos = await getCollection("videos", (entry) => {
+ return (
+ entry.data.link.startsWith("https://youtu") &&
+ entry.data.products?.some((v: string) => products.includes(v))
+ );
+});
+
+const entries = videos.map((video) => ({
+ href: video.data.link,
+ title: video.data.id,
+ description: video.data.description,
+}));
+---
+
+
diff --git a/src/components/index.ts b/src/components/index.ts
index 3e307aeb6baaf0c..e2af73f4e77015e 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -63,6 +63,7 @@ export { default as WorkersArchitectureDiagram } from "./WorkersArchitectureDiag
export { default as WorkersIsolateDiagram } from "./WorkersIsolateDiagram.astro";
export { default as WorkerStarter } from "./WorkerStarter.astro";
export { default as YouTube } from "./YouTube.astro";
+export { default as YouTubeVideos } from "./YouTubeVideos.astro";
// Taken from Astro
export { default as ListCard } from "./astro/ListCard.astro";
diff --git a/src/content/docs/style-guide/components/youtube-videos.mdx b/src/content/docs/style-guide/components/youtube-videos.mdx
new file mode 100644
index 000000000000000..26ebf0ed7675040
--- /dev/null
+++ b/src/content/docs/style-guide/components/youtube-videos.mdx
@@ -0,0 +1,23 @@
+---
+title: YouTube Videos
+styleGuide:
+ component: YouTubeVideos
+---
+
+## Usage
+
+```mdx live
+import { YouTubeVideos } from "~/components";
+
+
+```
+
+## `` Props
+
+### `products`
+
+**type:** `string[]`
+
+An array of products to show associated videos for.
+
+If not specified, the product where the component is used will be used.