New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug(admin): Admin view of Blocks nested within a Page don't load default locale data #6292
Comments
Hey there! This is intended functionality actually. We could make it configurable in the future of course but right now the admin UI explicitly calls for fallback-locale=null. Are you interested in us making this configurable for the admin panel? Open a feature request on the main Payload repository if so and we will do what we can! |
Hi @jmikrut ! Thank you for the quick response. The fact that the content fields are blank isn't so much the issue. The real problem is that the live update seems to pull directly from the content fields. So when they're blank they make it look like the live preview has no content at all, which is different than what you see on the actual live site. Here's what we're using for the import { useCallback, useEffect, useRef, useState } from 'react';
import { ready, subscribe, unsubscribe } from '@payloadcms/live-preview';
const useLivePreview = <T>(props: {
depth?: number;
initialData: T;
serverURL: string;
}): {
data: T;
isLoading: boolean;
} => {
const { depth = 0, initialData } = props;
const [data, setData] = useState<T>(initialData);
const [isLoading, setIsLoading] = useState<boolean>(true);
const hasSentReadyMessage = useRef<boolean>(false);
const onChange = useCallback((mergedData: T) => {
// When a change is made, the `onChange` callback will be called with the merged data
// Set this merged data into state so that React will re-render the UI
setData(mergedData);
setIsLoading(false);
}, []);
useEffect(() => {
// Listen for `window.postMessage` events from the Admin panel
// When a change is made, the `onChange` callback will be called with the merged data
const serverURL = window.location.origin;
const subscription = subscribe({
callback: onChange,
depth,
initialData,
serverURL,
apiRoute: '/api'
});
// Once subscribed, send a `ready` message back up to the Admin panel
// This will indicate that the front-end is ready to receive messages
if (!hasSentReadyMessage.current) {
hasSentReadyMessage.current = true;
ready({
serverURL
});
}
// When the component unmounts, unsubscribe from the `window.postMessage` events
return () => {
unsubscribe(subscription);
};
}, [onChange, depth, initialData]);
return {
data,
isLoading
};
};
export default useLivePreview; Correct me if I'm wrong, but I believe the |
Ohhhhhh I see. I will convert this to an issue on the main Payload repo and we will solve for it there. Also, today we released server component support for live preview which would not have this problem. You can check that out in the beta branch documentation - but this is definitely something that should be solved in the useLivePreview hook for sure. On it. |
Oh excellent. I'll check out the server component support. Thank you @jmikrut !!! |
I was able to get it kind of working with this code: import { useCallback, useEffect, useRef, useState } from 'react';
import { ready, subscribe, unsubscribe } from '@payloadcms/live-preview';
import * as R from 'ramda';
const isObject = (val: unknown) =>
val && typeof val === 'object' && !Array.isArray(val);
const mergeArrays = (arr1: unknown[], arr2: unknown[]): unknown[] => {
return R.range(0, Math.max(arr1.length, arr2.length)).map((i: number) => {
if (arr1[i] === undefined) {
return arr2[i];
}
if (arr2[i] === undefined) {
return arr1[i];
}
if (isObject(arr1[i]) || isObject(arr2[i])) {
// eslint-disable-next-line
return deepMerge(arr1[i], arr2[i]);
}
return arr2[i];
});
};
const deepMerge = <T, U>(obj1: T, obj2: U): T => {
return R.mergeWithKey(
(_key: string, left: object, right: object) => {
if (isObject(left) || isObject(right)) {
// lexical content merge
if (Object.hasOwn(right ?? left, 'root')) {
if (right) {
return right;
}
return left;
}
return deepMerge(left, right);
}
if (Array.isArray(left) && Array.isArray(right)) {
return mergeArrays(left, right);
}
return right;
},
obj1,
obj2
);
};
const useLivePreview = <T>(props: {
depth?: number;
initialData: T;
serverURL: string;
}): {
data: T;
isLoading: boolean;
} => {
const { depth = 0, initialData } = props;
const [data, setData] = useState<T>(initialData);
const [isLoading, setIsLoading] = useState<boolean>(true);
const hasSentReadyMessage = useRef<boolean>(false);
const onChange = useCallback((mergedData: T) => {
// When a change is made, the `onChange` callback will be called with the merged data
// Set this merged data into state so that React will re-render the UI
setData(deepMerge(R.clone(initialData), R.clone(mergedData)));
setIsLoading(false);
}, []);
useEffect(() => {
// Listen for `window.postMessage` events from the Admin panel
// When a change is made, the `onChange` callback will be called with the merged data
const serverURL = window.location.origin;
const subscription = subscribe({
callback: onChange,
depth,
initialData: R.clone(initialData),
serverURL,
apiRoute: '/api'
});
// Once subscribed, send a `ready` message back up to the Admin panel
// This will indicate that the front-end is ready to receive messages
if (!hasSentReadyMessage.current) {
hasSentReadyMessage.current = true;
ready({
serverURL
});
}
// When the component unmounts, unsubscribe from the `window.postMessage` events
return () => {
unsubscribe(subscription);
};
}, [onChange, depth, initialData]);
return {
data,
isLoading
};
};
export default useLivePreview; This isn't ideal but it's working as a stop-gap until someone pushes a real fix. |
Expected behavior:
When switching to non-default locales, if a translated value has not been provided, the admin editor should load the content from the default locale.
Current behavior:
When switching to non-default locales, nested block data is empty in the admin view.
Setup:
I was able to reproduce with the latest from the
main
branch of this repo, using payload version3.0.0-beta.24
.I made a couple of changes to the
payload.config.ts
file to test nested blocks with locales. Here is the full config with the changes commented:Notes
When loading the content into the front-end of my app, it does seem to pull in the default locale data.
It's only the admin view where the localized values are empty.
The text was updated successfully, but these errors were encountered: