fix: prevent hero image flash by aligning server/client random seed
All checks were successful
CI / update (push) Successful in 1m28s
All checks were successful
CI / update (push) Successful in 1m28s
Generate heroIndex on the server and pass it to the client so SSR and hydration pick the same hero recipe, eliminating the image swap on first interaction.
This commit is contained in:
@@ -19,6 +19,7 @@ export const load: PageServerLoad = async ({ fetch, locals, params }) => {
|
|||||||
return {
|
return {
|
||||||
season: addFavoriteStatusToRecipes(item_season, userFavorites),
|
season: addFavoriteStatusToRecipes(item_season, userFavorites),
|
||||||
all_brief: addFavoriteStatusToRecipes(item_all_brief, userFavorites),
|
all_brief: addFavoriteStatusToRecipes(item_all_brief, userFavorites),
|
||||||
session
|
session,
|
||||||
|
heroIndex: Math.random()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
// Only recipes with hashed images (e.g. myrecipe.a1b2c3d4.webp)
|
// Only recipes with hashed images (e.g. myrecipe.a1b2c3d4.webp)
|
||||||
const hasHashedImage = (r) => r.images?.length > 0 && /\.\w+\.\w+$/.test(r.images[0].mediapath);
|
const hasHashedImage = (r) => r.images?.length > 0 && /\.\w+\.\w+$/.test(r.images[0].mediapath);
|
||||||
|
|
||||||
// Pick once on mount — not reactive, so image and link always match
|
// Server-generated random index ensures SSR and client pick the same hero
|
||||||
const heroIndex = Math.random();
|
const heroIndex = data.heroIndex;
|
||||||
const heroRecipe = $derived.by(() => {
|
const heroRecipe = $derived.by(() => {
|
||||||
const seasonPool = data.season.filter(hasHashedImage);
|
const seasonPool = data.season.filter(hasHashedImage);
|
||||||
const pool = seasonPool.length > 0 ? seasonPool : data.all_brief.filter(hasHashedImage);
|
const pool = seasonPool.length > 0 ? seasonPool : data.all_brief.filter(hasHashedImage);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export async function load({ data }) {
|
|||||||
...data,
|
...data,
|
||||||
all_brief: rand_array(allBrief),
|
all_brief: rand_array(allBrief),
|
||||||
season: rand_array(seasonRecipes),
|
season: rand_array(seasonRecipes),
|
||||||
|
heroIndex: Math.random(),
|
||||||
isOffline: true
|
isOffline: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user