"use client"; import React from "react"; import { useFormFields } from "@payloadcms/ui"; /** Extract an 11-char YouTube video id from common URL shapes (or a bare id). */ function extractYouTubeId(input: unknown): string | null { if (typeof input !== "string") return null; const url = input.trim(); if (!url) return null; if (/^[\w-]{11}$/.test(url)) return url; // already just an id const patterns = [ /(?:youtube\.com\/watch\?[^#]*\bv=)([\w-]{11})/i, /(?:youtu\.be\/)([\w-]{11})/i, /(?:youtube\.com\/embed\/)([\w-]{11})/i, /(?:youtube\.com\/shorts\/)([\w-]{11})/i, /(?:youtube\.com\/live\/)([\w-]{11})/i, ]; for (const p of patterns) { const m = url.match(p); if (m?.[1]) return m[1]; } return null; } export interface YouTubePreviewProps { /** Form path of the field holding the YouTube URL (e.g. "media.youtube"). */ sourcePath?: string; } /** * Renders a live, embedded YouTube preview from the sibling URL field. Virtual * (a `ui` field) — it stores nothing; the URL lives on the `youtube` text * field, which is what syncs to Typesense. */ export function YouTubePreview({ sourcePath = "media.youtube", }: YouTubePreviewProps) { const value = useFormFields(([fields]) => fields?.[sourcePath]?.value); const id = extractYouTubeId(value); return (
Paste a YouTube URL above to preview it here.
)}