Guys comming back to this.
I managed to implement a pretty barebones routing solution based on my last response, here's how anyone can replicate it (as a heads up, this was implemented inside a module that's used in all of our existing apps as a Navbar component)
first of all, i'll contextualize everyone on the component we have, it's this module:
which looks something like this when used:
The module expects a pageUrl
variable, which should always be the url.href
value of the app (for multipage-apps)

or urlparams.href
for singlepage-apps

this means that the module will always have the current url the user is viewing as context, with this configuration, I created 3 JS queries to manage the pageStack
array with localStorage, here's how i did it:

I'll start with the pageStackRouter
query
function splitUrl(url) {
const [base, hash] = url.split("#");
return { base, hash: hash || "" };
}
const currentUrl = splitUrl(pageUrl.value);
const sanitizedBase = currentUrl.base;
const currentHash = currentUrl.hash;
let pageStackStorage = localStorage.values?.pageStack || [];
let currentPageId = localStorage.values?.currentPageId ?? (pageStackStorage[pageStackStorage.length - 1]?.id ?? -1);
// Check if the current URL matches the expected entry at `currentPageId`
const expectedEntry = pageStackStorage.find(page => page.id === currentPageId);
if (expectedEntry?.base === sanitizedBase) {
// Navigation is due to back/forward: update hash, do NOT add to stack
expectedEntry.hash = currentHash;
} else {
// User-initiated navigation: check against last entry
const lastPage = pageStackStorage[pageStackStorage.length - 1];
if (!lastPage || lastPage.base !== sanitizedBase) {
// Truncate the stack if navigating from a non-latest position (like browser history)
const truncateIndex = pageStackStorage.findIndex(page => page.id === currentPageId);
pageStackStorage = pageStackStorage.slice(0, truncateIndex + 1);
// Add new entry
const newEntry = { id: Date.now(), base: sanitizedBase, hash: currentHash }; // Use unique ID (e.g., timestamp)
pageStackStorage = [...pageStackStorage, newEntry];
currentPageId = newEntry.id;
} else {
// Update hash of the last entry
lastPage.hash = currentHash;
}
}
// Persist changes
localStorage.setValue("pageStack", pageStackStorage);
localStorage.setValue("currentPageId", currentPageId);
This code uses the pageUrl
variable value, if the pageStack
is empty or doesn't exist in localStorage, initializes the variable & stores it, if there's an existing value, it'll update the array and add the url to it (with hash params included, if they come in the variable) IF the last page visited is not the same, if it's the same, it'll only update the params, it's worth mentioning that this query runs on every page load
For the Back & forwad navigation i defined these scripts:
const currentEntry = localStorage.values?.pageStack?.find(page => page.id === localStorage.values?.currentPageId);
if (currentEntry) {
// Find the index of the current entry
const currentIndex = localStorage.values?.pageStack?.findIndex(page => page.id === localStorage.values?.currentPageId);
// Check if the current index is valid and not the first entry
if (currentIndex > 0) {
// Get the previous page in the stack
const previousPage = localStorage.values?.pageStack[currentIndex - 1];
// Construct the full URL with the hash (if it exists)
const fullUrl = previousPage.hash
? `${previousPage.base}#${previousPage.hash}`
: previousPage.base;
// Update currentPageId to the previous entry's ID
localStorage.setValue("currentPageId", previousPage.id);
// Navigate to the previous page
utils.openUrl(fullUrl, {newTab: false, forceReload: true});
}
}
const currentEntry = localStorage.values?.pageStack?.find(page => page.id === localStorage.values?.currentPageId);
if (currentEntry) {
// Find the index of the current entry
const currentIndex = localStorage.values?.pageStack?.findIndex(page => page.id === localStorage.values?.currentPageId);
// Check if the current index is valid and not the last entry
if (currentIndex < localStorage.values?.pageStack?.length - 1) {
// Get the next page in the stack
const nextPage = localStorage.values?.pageStack[currentIndex + 1];
// Construct the full URL with the hash (if it exists)
const fullUrl = nextPage.hash
? `${nextPage.base}#${nextPage.hash}`
: nextPage.base;
// Update currentPageId to the next entry's ID
localStorage.setValue("currentPageId", nextPage.id);
// Navigate to the next page
utils.openUrl(fullUrl, {newTab: false, forceReload: true});
}
}
with this, the configuration had to be done ONCE (navbar component is used as default header of our apps) so the propagation of this new feature was easy to implement in our ecosystem.
almost forgot, here's an example of how the localStorage.values.pageStack
looks after the user navigates to a few apps:
[
{
"id": 1741706427501,
"base": "url0",
"hash": "code=&country=&pageNumber=&pageSize=&phone=&userId="
},
{
"id": 1741707727308,
"base": "url1",
"hash": ""
},
{
"id": 1741707807641,
"base": "url2",
"hash": ""
},
{
"id": 1741707811489,
"base": "url3",
"hash": ""
}
]
And a really important key currentPageId: 1741707811489
, this one is also stored in localStorage & is used to find the currentPage in the stack & navigate accordingly based on it's position (to avoid a navigation loop when going backwards/forwards)
I know there might be a few caveats i'm missing but as far as this implementation goes, it gives us a head start to experiment with some routing from now on (until we got a native routing solution from Retool)
Let me know if it works for you, hit me up if you have any doubts about this implementation!