From 8edc692ead290b2cbe15ef6c86f3a79cf7ba4c15 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:48:10 -0700 Subject: [PATCH 1/3] patch(jsonld): use VideoGallery, rm slice --- app/[locale]/videos/page-jsonld.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/[locale]/videos/page-jsonld.tsx b/app/[locale]/videos/page-jsonld.tsx index c9f14cddc7e..44a650591a0 100644 --- a/app/[locale]/videos/page-jsonld.tsx +++ b/app/[locale]/videos/page-jsonld.tsx @@ -4,9 +4,10 @@ import type { VideoCardData } from "@/lib/types" import PageJsonLD from "@/components/PageJsonLD" -import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants" import { normalizeUrlForJsonLd } from "@/lib/utils/url" +import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants" + export default async function VideosPageJsonLD({ locale, videos, @@ -23,7 +24,7 @@ export default async function VideosPageJsonLD({ "@graph": [ ...BASE_GRAPH_NODES, { - "@type": "CollectionPage", + "@type": "VideoGallery", "@id": url, name: t("page-videos-meta-title"), description: t("page-videos-meta-description"), @@ -66,7 +67,6 @@ export default async function VideosPageJsonLD({ ? -1 : 0 ) - .slice(0, 10) .map((video, index) => ({ "@type": "ListItem", position: index + 1, From e0add53a060c9d47c5f3b1501ed8009683578b76 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:50:32 -0700 Subject: [PATCH 2/3] patch(jsonld): add base nodes/WebPage, isPartOf - Adds type-assertion node to reference VideoObject as "isPartOf" the parent VideoGallery - Includes WebPage node with "mainEntity" pointing to the VideoObject - Replaced ORGANIZATION with REFERENCE for EF publisher (node now available from BASE_GRAPH_NODES) --- app/[locale]/videos/[slug]/page-jsonld.tsx | 113 +++++++++++++++------ 1 file changed, 82 insertions(+), 31 deletions(-) diff --git a/app/[locale]/videos/[slug]/page-jsonld.tsx b/app/[locale]/videos/[slug]/page-jsonld.tsx index 3e14d3e4e57..21823e63d83 100644 --- a/app/[locale]/videos/[slug]/page-jsonld.tsx +++ b/app/[locale]/videos/[slug]/page-jsonld.tsx @@ -1,3 +1,5 @@ +import { getTranslations } from "next-intl/server" + import type { VideoFrontmatter } from "@/lib/interfaces" import PageJsonLD from "@/components/PageJsonLD" @@ -6,9 +8,10 @@ import { stripMarkdown } from "@/lib/utils/md" import { toIsoDuration } from "@/lib/utils/time" import { normalizeUrlForJsonLd } from "@/lib/utils/url" import { getDefaultThumbnailUrl } from "@/lib/utils/videos" -import { ORGANIZATION } from "@/lib/jsonld/constants" -export default function VideoPageJsonLD({ +import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants" + +export default async function VideoPageJsonLD({ locale, slug, frontmatter, @@ -20,37 +23,85 @@ export default function VideoPageJsonLD({ transcript: string | null }) { const url = normalizeUrlForJsonLd(locale, `/videos/${slug}/`) + const videoGalleryUrl = normalizeUrlForJsonLd(locale, "/videos/") - const jsonLd: Record = { - "@context": "https://schema.org", - "@type": "VideoObject", - "@id": `${url}#video`, - name: frontmatter.title, - description: frontmatter.description, - uploadDate: `${frontmatter.uploadDate}T00:00:00+00:00`, - duration: toIsoDuration(frontmatter.duration), - thumbnailUrl: - frontmatter.customThumbnailUrl || - getDefaultThumbnailUrl(frontmatter.youtubeId), - embedUrl: `https://www.youtube.com/embed/${frontmatter.youtubeId}`, - contentUrl: `https://www.youtube.com/watch?v=${frontmatter.youtubeId}`, - educationalLevel: frontmatter.educationLevel, - inLanguage: frontmatter.lang, - creator: { - "@type": "Person", - name: frontmatter.author, - }, - publisher: ORGANIZATION.ETHEREUM_FOUNDATION, - isAccessibleForFree: true, - isFamilyFriendly: true, - } + const t = await getTranslations("page-videos") + + const mainEntityId = { "@id": `${url}#video` } - // Add transcript as plain text if available - if (transcript) { - // Escape < and / to prevent script injection (XSS protection) - jsonLd.transcript = stripMarkdown(transcript, true) - .replace(/ From 93e2cecee8f4acb7c3e2d3f5cef4c197bff55e56 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 23 Apr 2026 13:25:10 -0700 Subject: [PATCH 3/3] refactor: semantic naming adjustment --- app/[locale]/videos/[slug]/page-jsonld.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/[locale]/videos/[slug]/page-jsonld.tsx b/app/[locale]/videos/[slug]/page-jsonld.tsx index 21823e63d83..56d938012cd 100644 --- a/app/[locale]/videos/[slug]/page-jsonld.tsx +++ b/app/[locale]/videos/[slug]/page-jsonld.tsx @@ -27,7 +27,7 @@ export default async function VideoPageJsonLD({ const t = await getTranslations("page-videos") - const mainEntityId = { "@id": `${url}#video` } + const videoObjectId = { "@id": `${url}#video` } const jsonLd = { "@context": "https://schema.org", @@ -69,11 +69,11 @@ export default async function VideoPageJsonLD({ }, publisher: REFERENCE.ETHEREUM_FOUNDATION, reviewedBy: REFERENCE.ETHEREUM_FOUNDATION, - mainEntity: mainEntityId, + mainEntity: videoObjectId, }, { "@type": "VideoObject", - ...mainEntityId, + ...videoObjectId, name: frontmatter.title, description: frontmatter.description, uploadDate: `${frontmatter.uploadDate}T00:00:00+00:00`,