import type { SandboxLocaleTag } from '@app/shared/i18n/locale-meta'; import type { PreloadValue } from '@app/shared/sandbox-listener'; import type { SourceId } from '@app/shared/sources'; import type { Preset, Skin, Styling } from '@app/types'; import { forwardRef, useEffect, useRef, useState } from 'react'; type PreviewProps = { pagePath: string; preset: Preset; skin: Skin; styling: Styling; source: SourceId; autoplay: boolean; muted: boolean; loop: boolean; preload: PreloadValue; locale: SandboxLocaleTag; }; export const Preview = forwardRef(function Preview( { pagePath, preset, skin, styling, source, autoplay, muted, loop, preload, locale }, ref ) { const buildUrl = (base: string, bustCache = false) => { const params = new URLSearchParams({ preset, skin, styling, source, autoplay: autoplay ? '1' : '0', muted: muted ? '1' : '0', loop: loop ? '1' : '0', preload, locale, }); if (bustCache) params.set('_', String(Date.now())); return `${base}?${params}`; }; const reloadOnLocale = pagePath === '/cdn/'; // Capture the initial query so the iframe doesn't reload when autoplay/muted // toggle — those changes are streamed in via postMessage. const [iframeUrl, setIframeUrl] = useState(() => buildUrl(pagePath)); const openUrl = buildUrl(pagePath); const previousLocaleRef = useRef(locale); // biome-ignore lint/correctness/useExhaustiveDependencies: keep iframe `src` locale in sync; other toggles use postMessage. useEffect(() => { if (previousLocaleRef.current === locale) return; previousLocaleRef.current = locale; setIframeUrl(buildUrl(pagePath, reloadOnLocale)); }, [locale, pagePath, reloadOnLocale]); return (
Open