From b0b781db1c8f9419e515d1824756ed3eb06a2987 Mon Sep 17 00:00:00 2001 From: Jason Buckner Date: Wed, 18 Mar 2026 17:56:11 -0700 Subject: [PATCH] Fix hash mode to preserve URL pathname window.location.replace('#fragment') is a relative URL navigation that can wipe the current pathname in SPA contexts. For example, /labs/details/goody becomes /#page/n5/mode/2up. Replace with window.location.hash = fragment, which only modifies the hash portion and always preserves the existing pathname. Co-Authored-By: Claude Opus 4.6 --- src/plugins/url/UrlPlugin.js | 4 +++- src/plugins/url/plugin.url.js | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/url/UrlPlugin.js b/src/plugins/url/UrlPlugin.js index f965674ba..4f1fd36cb 100644 --- a/src/plugins/url/UrlPlugin.js +++ b/src/plugins/url/UrlPlugin.js @@ -151,7 +151,9 @@ export class UrlPlugin { } if (this.urlMode == 'hash') { - window.location.replace('#' + concatenatedPath); + // Use location.hash instead of location.replace('#...') to preserve + // the current pathname in SPA contexts. + window.location.hash = concatenatedPath; } this.oldLocationHash = urlStrPath; } diff --git a/src/plugins/url/plugin.url.js b/src/plugins/url/plugin.url.js index 6f9368ded..b26fd2d40 100644 --- a/src/plugins/url/plugin.url.js +++ b/src/plugins/url/plugin.url.js @@ -206,7 +206,10 @@ BookReader.prototype.urlUpdateFragment = function() { } else if (this.textFragmentPage && extractedPage != this.textFragmentPage) { textFragment = ''; } - window.location.replace('#' + newFragment + newQueryStringSearch + textFragment); + // Use location.hash instead of location.replace('#...') to preserve + // the current pathname. location.replace('#foo') is a relative URL + // that can wipe the path in SPA contexts. + window.location.hash = newFragment + newQueryStringSearch + textFragment; this.oldLocationHash = newFragment + newQueryStringSearch + textFragment; } };