From a46a6d55eb7912e1f917af35c33f6de28429e09e Mon Sep 17 00:00:00 2001 From: Jonathan Herlin Date: Wed, 2 Sep 2026 14:51:30 +0200 Subject: [PATCH] fix: use replaceState for traces/roles redirects to preserve back-button history (#1883) fix: use replaceState for traces/roles redirects to preserve back-button history The #/traces/ and #/roles backward-compat redirects used location.hash = ..., which pushes a new history entry instead of replacing the current one. This trapped users navigating back from a trace view: the intermediate #/traces/ entry would immediately re-redirect forward again on hashchange, so back button never reached the packets view they came from. --- public/app.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/public/app.js b/public/app.js index dcfa6e3b..4455bbbb 100644 --- a/public/app.js +++ b/public/app.js @@ -1039,16 +1039,20 @@ function navigate() { closeNav(); // Backward-compat redirect: #/traces/ → #/tools/trace/ (issue #944). + // Uses replaceState (not location.hash =) so this redirect doesn't add its + // own history entry, otherwise the back button gets stuck bouncing off it. if (location.hash.startsWith('#/traces/')) { - location.hash = location.hash.replace('#/traces/', '#/tools/trace/'); + history.replaceState(null, '', location.hash.replace('#/traces/', '#/tools/trace/')); + navigate(); return; } // Backward-compat redirect: #/roles → #/analytics?tab=roles (issue #1085). // The Roles page was folded into the Analytics tab strip; old links and - // bookmarks must keep working. + // bookmarks must keep working. Uses replaceState for the same reason as above. if (location.hash === '#/roles' || location.hash.startsWith('#/roles?') || location.hash.startsWith('#/roles/')) { - location.hash = '#/analytics?tab=roles'; + history.replaceState(null, '', '#/analytics?tab=roles'); + navigate(); return; }