diff --git a/web/SitePreview.tsx b/web/SitePreview.tsx index 51880a4..0ccbd67 100644 --- a/web/SitePreview.tsx +++ b/web/SitePreview.tsx @@ -226,6 +226,31 @@ export const SitePreview = ({ setLoaded(0); }, [reloadToken, changed]); + /* + Reload by NAVIGATING the frame, not by replacing it. + + The frame used to carry `key={reloadToken}`, so a reload was a new element: React unmounted the old + one and the panel went white until the new document arrived. On a page whose crop has just changed + that is not instant — the site is asking av-club for a fresh ladder — so every framing adjustment + flashed an empty panel for a second or two, which reads as the preview breaking. + + A browser keeps painting the current document while the next one is being fetched. So the same + element stays, and the old page is on screen until the new one commits. + + Same origin, through the dev proxy, which is what makes `contentWindow` reachable at all. + + Skipped on the first run: the element has only just mounted and is already loading its document. + */ + const first = useRef(true); + + useEffect(() => { + if (first.current) { + first.current = false; + return; + } + frame.current?.contentWindow?.location.reload(); + }, [reloadToken, changed]); + useEffect(() => { if (!loaded) return; const frameDocument = frame.current?.contentDocument; @@ -345,9 +370,8 @@ export const SitePreview = ({ remove the attribute. This is the owner's own development server on this machine. */