HomeComponentRenderer
Draws one home page block from its API data: finds its registered component, wraps it in an error boundary, and defers it until visible.
import { HomeComponentRenderer } from '@salla.sa/twilight-theme-engine/components/home';In plain words
The engine's home page is a loop over the merchant's block list, and this is what draws each entry. For one block it finds the component registered for its path, shows a grey placeholder until the block scrolls near the screen, and keeps a block that crashes from taking the rest of the page down.
You need it only when you build your own home page from the block list.
Signature
const HomeComponentRenderer: React.MemoExoticComponent<(props: {
data: HomeComponentData; // one entry of home.queries.components()
index: number; // its place in the list, from 0
}) => JSX.Element>
interface HomeComponentData { // @salla.sa/twilight-theme-engine/types
path: string;
key?: string | number | null;
view_style?: string | null;
[key: string]: …;
}Try it live
Loading the home page blocks…
import { useQuery } from '@tanstack/react-query';
import { home } from '@salla.sa/twilight-theme-engine/api/home';
import { HomeComponentRenderer } from '@salla.sa/twilight-theme-engine/components/home';
export function HomeBlocks() {
const { data = [] } = useQuery(home.queries.components());
return data.map((block, index) => (
<HomeComponentRenderer
key={block.key ?? JSON.stringify(block)}
// The engine's home loader strips the "home." prefix theme blocks arrive with.
data={{ ...block, path: block.path.replace('home.', '') }}
index={index}
/>
));
}
Example
import { useQuery } from '@tanstack/react-query';
import { home } from '@salla.sa/twilight-theme-engine/api/home';
import { HomeComponentRenderer } from '@salla.sa/twilight-theme-engine/components/home';
export function HomeBlocks() {
const { data = [] } = useQuery(home.queries.components());
return data.map((block, index) => (
<HomeComponentRenderer
key={block.key ?? JSON.stringify(block)}
data={{ ...block, path: block.path.replace('home.', '') }}
index={index}
/>
));
}
How it behaves
Lookup:
home:<path>:<view_style>when the block has aview_style, thenhome:<path>, then a fallback that shows a yellow "Unknown component" card in development and nothing in production.The component receives
data={{ ...data, position: index + 1, priority: index <= 2 }}, insideComponentErrorBoundarywithposition={index + 1}.The wrapper is
RenderWhenVisible(from/components/common): blocks withindex0 to 2 render at once; later ones are not in the React tree until they come within 50px of the viewport, so their effects and requests wait too.Wrapper shell per path (reserved height, placeholder, class, id): a config registered with
registerHomeComponentConfig, else the built-in one for engine blocks, elses-block s-block--<path>, 400px and the products-slider skeleton.The engine's
HomePagerendershome:startandhome:contentslots, then one renderer per block withkey={data.key ?? JSON.stringify(data)}, thenhome:end. Its loader stripshome.from each path, which theme blocks arrive with (home.brands).
Gotchas
Pass paths without the
home.prefix. The API sends theme blocks ashome.<name>; given the raw list, the renderer looks uphome:home.brandsand finds nothing.It logs
[HomeComponentRenderer] MOUNTandUNMOUNTwithconsole.logfor every block, in production builds too: only the per-render log is limited to development.prioritygoes insidedata.FixedBannerreads a top-levelpriorityprop, so through the renderer a banner at the top of the page is never loaded eagerly.
Related
Tells the engine which component draws each home page block, by the block path the Salla API sends. Call it once at startup.
registerHomeComponentConfigSets the placeholder, reserved height, class and id HomeComponentRenderer uses around your own home blocks before they load.
ComponentErrorBoundaryCatches an error thrown while a home block renders, logs it, and shows nothing in production so the rest of the page survives.