From 1c818e648bcb5013d9c52ccb9d4ad2422f922237 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 25 Mar 2026 11:20:44 -0400 Subject: [PATCH] fix(idaa): break sys_menu reactive loop + restore menu on iframe=false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes in the IDAA root layout: 1. Add missing `untrack` import and wrap `$ae_loc.sys_menu.hide = false` in `untrack()` inside the trusted-access effect. Without this, reading $ae_loc.iframe/$ae_loc.trusted_access and then writing back to $ae_loc caused an infinite reactive loop → effect_update_depth_exceeded error. Only hit by trusted/admin users in iframe mode (regular Novi members at authenticated_access were unaffected). 2. When iframe URL param is explicitly set to 'false', restore $ae_loc.sys_menu.hide = false. The root layout sets it to true on iframe=true but never resets it, leaving the system bar permanently hidden after leaving iframe mode. Co-Authored-By: Claude Sonnet 4.6 --- src/routes/idaa/+layout.svelte | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/routes/idaa/+layout.svelte b/src/routes/idaa/+layout.svelte index 3b9fb362..7157a037 100644 --- a/src/routes/idaa/+layout.svelte +++ b/src/routes/idaa/+layout.svelte @@ -2,6 +2,7 @@ let log_lvl: number = 0; // *** Import Svelte specific +import { untrack } from 'svelte'; import { browser } from '$app/environment'; import { afterNavigate } from '$app/navigation'; @@ -202,7 +203,13 @@ $effect(() => { $ae_loc.iframe = false; document.getElementsByTagName('html')[0].classList.remove('iframe'); - // document.getElementsByTagName('html')[0].classList.add('light'); + // data_struct['iframe'] = false; + // WHY: The root layout sets sys_menu.hide=true when iframe=true, but never + // restores it. We restore it here so the system bar reappears when the URL + // param is explicitly set to false (e.g. admin toggling embed mode off). + untrack(() => { + $ae_loc.sys_menu.hide = false; + }); } }); @@ -211,7 +218,13 @@ $effect(() => { // the iframe src to pass show_menu=true, so we watch for trusted_access and unhide it. $effect(() => { if (browser && $ae_loc.iframe && $ae_loc.trusted_access) { - $ae_loc.sys_menu.hide = false; + // WHY untrack: writing to $ae_loc inside an effect that reads $ae_loc causes + // an infinite reactive loop (effect_update_depth_exceeded). The conditions we + // want to react to ($ae_loc.iframe / trusted_access) are tracked above; the + // write is a side-effect that must not re-trigger this effect. + untrack(() => { + $ae_loc.sys_menu.hide = false; + }); } });