Live Preview breaks when preview frame context changes
Link to reproduction
No response
Describe the Bug
TL;DR
Live Preview stops functioning when the preview frame changes context, either by navigating (away and back to the same page) or by refreshing.
Any changes after a context change result in a console warning and an empty data object being returned. Warning:
Payload Live Preview: No `fieldSchemaJSON` was received from the parent window. Unable to merge data.
This occurs both for @payloadcms/live-preview and @payloadcms/live-preview-react, both exhibiting the same issue. This appears to be a Payload bug, rather than anything specific to the front-end.
Context
My Next (app router) site uses the useLivePreview hook to watch for when data.updatedAt changes, then calls router.refresh()- using Next's dynamic rendering via Draft Mode to fetch the new version of the document, rather than hot-swapping out the page data onChange. I've gone with this strategy to avoid having page-level client components - this is a pre-existing Next app we're migrating from a different CMS, and I'd like to avoid structural changes to the front-end's architecture.
To achieve this, I have a <DraftIndicator> client component that renders in app/layout.tsx if Next is in Draft Mode. Live Preview hits an api route to enable Draft Mode. This component uses the following code to watch for changes to data.updatedAt, refreshing when it changes.
const lastUpdatedAt = useRef<string>();
const { data } = useLivePreview({
serverURL: process.env.NEXT_PUBLIC_PAYLOAD_URL ?? "",
initialData: {} as { [key: string]: any },
});
useEffect(() => {
if (!lastUpdatedAt.current && data.updatedAt) {
lastUpdatedAt.current = data.updatedAt;
return;
}
if (data.updatedAt && lastUpdatedAt.current !== data.updatedAt) {
lastUpdatedAt.current = data.updatedAt;
console.log("Change in `updatedAt` detected, refreshing page.");
router.refresh();
}
}, [data]);
I recognise that this is a non-standard and likely unexpected use of the useLivePreview hook, but I believe the underlying bug of frame context changes breaking Payload's Live Preview functionality to still be a valid issue worth resolving. End users will not necessarily intuit that navigating away and then back to the same document would stop the Live Preview from updating.
To Reproduce
- Setup a Payload instance, with a collection that utilises Live Preview.
- Hook up a front-end that utilises the
useLivePreviewhook. - Within Payload's admin UI preview frame:
- Navigate away and back again
- Right Click > Reload Frame
- Update some document data and check the console for the following warning:
Payload Live Preview: No `fieldSchemaJSON` was received from the parent window. Unable to merge data. - Observe that changes made in the Admin UI are no longer reflected in the preview frame
Payload Version
2.8.2
Adapters and Plugins
@payloadcms/plugin-cloud, @payloadcms/live-preview-react
I have observed that the preview's iframe seems to re-render and hard navigate when hosted (Payload Cloud), which does not happen locally - I believe this might be related. This is true even pointing to the same hosted front-end. This issue seems to only occur when hard navigation takes place.
If Payload is hosted locally, all soft navigation stays soft, and this issue does not occur. But if Payload is hosted, all soft navigation becomes hard navigation, and this issue occurs.
A workaround that worked in my case was to use a nested iframe. Then even with a reload on navigation on that page would only happen in the nested iframe. and the iframe that payload uses wouldn't navigate.