Conversation
Add VideoFrontmatter interface extending SharedFrontmatter with video-specific fields (youtubeId, uploadDate, duration, topic as string[], etc). Replace Video/VideoMeta/VideoWithMeta with VideoData and VideoCardData types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename transcript.md to index.md for all 42 videos. Merge metadata from videos.json into YAML frontmatter (youtubeId, uploadDate, duration, educationLevel, topic as array, format, author, lang, breadcrumb). This consolidates the split data model into a single source of truth per video. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite videos.ts to read video data from index.md frontmatter via readdir + gray-matter instead of videos.json. Delete videos.json and videoTranscripts.ts (logic merged into videos.ts). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add optional boolean parameter to preserve paragraph structure instead of collapsing all whitespace. Used by video JSON-LD transcript output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update VideoWatch to use getVideoData and conditionally hide transcript link. Delete Transcript, TranscriptContent (inlined into page.tsx), VideoGalleryFilter (moved to _components/), and barrel export from src/components/Videos/. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add VideoGalleryFilter, constants.ts (VIDEO_CATEGORIES), and utils.ts (getVideosByCategory) under the /videos route. Update listing page to use filesystem-based getVideos() and colocated imports. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite video detail page to use getVideoData with frontmatter, SimpleHero, Breadcrumbs, formatDate, renderSimpleMarkdown for transcript, and forceMount accordion for SEO. Update JSON-LD to accept VideoFrontmatter and use shared stripMarkdown. Update translation keys. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove PR-added Playwright test files for video utilities. These tested the old JSON-based data layer and are not needed for production. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unused CSS classes from VideoWatch, delete e2e video tests from PR, and remove 5 unused i18n keys from page-videos.json. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Review cleanupPerformance
Dead code removed
DRY / cleanup
Reviewed by Claude Opus 4.6 |
|
@pettinarip Wouldn't merge this without checking with @mnelsonBT but marking it for code review |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Extract escapeHeadingIds to shared module and add remark-heading-id plugin to renderSimpleMarkdown so video transcripts can use {#custom-header-ids}.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Replaces `sddefault` (640x480) which is not guaranteed to exist Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
| @@ -1,8 +1,10 @@ | |||
| import { compileMDX, type MDXRemoteProps } from "next-mdx-remote/rsc" | |||
| import remarkGfm from "remark-gfm" | |||
| import remarkHeadingId from "remark-heading-id" | |||
There was a problem hiding this comment.
markdownlint enforcing header ID's on all content -- This enables proper parsing when using renderSimple approach. Compatible for even simpler markdown where these ID's won't be present (e.g., externally fetched data)
| label: t("nav-videos-label"), | ||
| description: t("nav-videos-description"), |
There was a problem hiding this comment.
Reminder note: These need translations
| /** | ||
| * Default YouTube thumbnail URL derived from a video ID. | ||
| * Returns hqdefault (480x360) which is guaranteed to exist. | ||
| */ | ||
| export function getDefaultThumbnailUrl(youtubeId: string): string { | ||
| return `https://img.youtube.com/vi/${youtubeId}/hqdefault.jpg` | ||
| } |
There was a problem hiding this comment.
sddefault.jpgnot always available (higher resolution)- Using
hqversion for now which is guaranteed to be available from YT - Conditionally rendering
sdif available requires several sequential fetches during build -- avoided - Future Trigger.dev task could load highest-quality image to s3 bucket so we can point to that instead
| { | ||
| variants: { | ||
| variant: { | ||
| semibold: "text-lg font-semibold", |
There was a problem hiding this comment.
Small addition here in lieu of hard-coding this styling into where the card is consumed
| // Preprocess the markdown content | ||
| function preprocessMarkdown(content: string) { | ||
| // Replace heading IDs without escaping to escaped version | ||
| // TODO: move to a separate file and test it more | ||
| return content.replace(/^(#{1,6}.*?)\{(#[\w-]+)\}/gm, "$1\\{$2\\}") | ||
| } | ||
|
|
There was a problem hiding this comment.
Shared -- abstracted to @/lib/md/escapeHeadingIds and renamed
| youtubeId: string | ||
| uploadDate: string | ||
| duration: string | ||
| educationLevel: "beginner" | "intermediate" | "advanced" |
There was a problem hiding this comment.
(Some of these are used for JSONLD and not rendered)
| { protocol: "https", hostname: "cdn.charmverse.io" }, | ||
| { protocol: "https", hostname: "ethwingman.com" }, | ||
| { protocol: "https", hostname: "eth-mcp.dev" }, | ||
| { protocol: "https", hostname: "img.youtube.com", pathname: "/vi/**" }, |
There was a problem hiding this comment.
If/when we implement Trigger.dev/s3 bucket handling for these, we could remove this
Summary
Refactors the video data architecture and page structure to align with site conventions.
Data layer
videos.jsoninto markdown frontmatter (index.md)transcript.mdtoindex.mdfor each videoVideoFrontmattertype, replaced oldVideo/VideoMeta/VideoWithMetatypesvideos.jsonandvideoTranscripts.ts(merged intovideos.ts)breadcrumbfrontmatter to all 42 videosstripMarkdowninstead of duplicatestripMdxComponents and organization
src/components/intoapp/[locale]/videos/_components/page.tsxVIDEO_CATEGORIESto colocatedconstants.ts,getVideosByCategorytoutils.tsVideoWatchshared component for new data layerSEO preserved
VideoObjectschema on every video detail pageforceMountgenerateStaticParamspre-renders all video pages at build timegenerateMetadatafor title and description meta tagsPreview links
Schema Markup Validator