reload the preview without blanking it
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) <noreply@anthropic.com>
This commit is contained in:
+27
-3
@@ -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.
|
||||
*/
|
||||
<iframe
|
||||
// The key is what makes `reloadToken` reload: a new key is a new element, so the browser
|
||||
// fetches the document again and `onLoad` runs, which re-injects the builder's chrome.
|
||||
key={`${reloadToken ?? 0}:${changed}`}
|
||||
// No key. See the reload effect above: replacing the element is what made the panel go
|
||||
// white between documents.
|
||||
ref={frame}
|
||||
// Applied on load as well as on change: the document is replaced on a reload, and the
|
||||
// properties go with it.
|
||||
|
||||
Reference in New Issue
Block a user