fix(recipe): View-Beacon ueber \$effect statt onMount
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 33s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 33s
Live-Test auf kochwas-dev: bei Hard-Reload/Cold-Start (nicht SPA-Click) landete kein view-Eintrag in der DB. Ursache: Recipe-Page-onMount feuert vor Layout-onMount, profileStore.load() laeuft aber im Layout- onMount und macht erst danach einen async fetch — zum Zeitpunkt des Beacons war profileStore.active noch null. Loesung: Beacon im \$effect, das auf profileStore.active reagiert. viewBeaconSent-Flag verhindert duplicate POSTs wenn der User waehrend der Page-Lifetime das Profil wechselt — der ursprueglich getrackte Profil-View bleibt der "richtige" fuer dieses Page-Open. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -356,19 +356,27 @@
|
||||
};
|
||||
document.addEventListener('visibilitychange', onVisibility);
|
||||
|
||||
// Track view per active profile (fire-and-forget). Skipped when no
|
||||
// profile is active — we'd just be writing rows nobody can sort against later.
|
||||
if (profileStore.active) {
|
||||
void fetch(`/api/recipes/${data.recipe.id}/view`, {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ profile_id: profileStore.active.id })
|
||||
});
|
||||
}
|
||||
|
||||
return () => document.removeEventListener('visibilitychange', onVisibility);
|
||||
});
|
||||
|
||||
// Track view per active profile (fire-and-forget). Lives in $effect, not
|
||||
// onMount, because profileStore.load() runs from layout's onMount and the
|
||||
// child onMount fires first — at mount time profileStore.active is still
|
||||
// null on cold loads. The effect re-runs once active populates, the
|
||||
// viewBeaconSent flag prevents duplicate POSTs on subsequent profile
|
||||
// switches within the same page instance.
|
||||
let viewBeaconSent = $state(false);
|
||||
$effect(() => {
|
||||
if (viewBeaconSent) return;
|
||||
if (!profileStore.active) return;
|
||||
viewBeaconSent = true;
|
||||
void fetch(`/api/recipes/${data.recipe.id}/view`, {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ profile_id: profileStore.active.id })
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
void releaseWakeLock();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user