fix: prevent hero image flash by aligning server/client random seed

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:
2026-02-16 14:43:15 +01:00
parent c21dcaa7ef
commit 37d7f28a72
3 changed files with 5 additions and 3 deletions
@@ -19,6 +19,7 @@ export const load: PageServerLoad = async ({ fetch, locals, params }) => {
return {
season: addFavoriteStatusToRecipes(item_season, 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)
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
const heroIndex = Math.random();
// Server-generated random index ensures SSR and client pick the same hero
const heroIndex = data.heroIndex;
const heroRecipe = $derived.by(() => {
const seasonPool = data.season.filter(hasHashedImage);
const pool = seasonPool.length > 0 ? seasonPool : data.all_brief.filter(hasHashedImage);
@@ -34,6 +34,7 @@ export async function load({ data }) {
...data,
all_brief: rand_array(allBrief),
season: rand_array(seasonRecipes),
heroIndex: Math.random(),
isOffline: true
};
}