From 2b2aacca14ac4ebeea49776af98ede91b3f96a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Tue, 1 Sep 2026 21:44:02 +0100 Subject: [PATCH] reload the preview without blanking it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The frame carried key={reloadToken}, so a reload was a NEW element: React unmounted the old one and the panel went white until the next document arrived. After a crop change that is not instant — the site is asking av-club for a fresh ladder — so every framing adjustment flashed an empty panel, which reads as the preview breaking. A browser keeps painting the current document while the next is being fetched. So the element stays and the frame is navigated instead. Same origin through the dev proxy, which is what makes contentWindow reachable. Co-Authored-By: Claude Opus 5 (1M context) --- web/SitePreview.tsx | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) 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. */