I can't think of any great solutions to your problem - it might not be possible (or I just don't know enough).
However, there is a workaround that may or may not be difficult to implement in your app depending on a number of factors. The history API allows you to do browser navigation as you've already found. The trick is to utilize it's ability to hold state at each point in browser history.
If, whenever a user navigates to a different part of your app, you implement the navigation with history.pushState(), and you add state like {allowBackNav:true}
to each navigation, then whenever the user clicks your backwards navigation button, you can ensure that allowBackNav is set to true on the history's state before allowing that actions. This state will be set for every moment in history except the point when the user first loaded your app.
This system will break if the user navigates to a part of your app through any other means besides your controlled history.pushState(), e.g. through a link.
Here's a complete working example.
<html>
<body>
<button id="back" onClick="back()" disabled>Back</button>
<button onClick="choose('A')">Option A</button>
<button onClick="choose('B')">Option B</button>
<button onClick="choose('C')">Option C</button>
<p id="option"></p>
<script>
window.back = function() {
history.back()
}
window.choose = function(option) {
history.pushState({allowBackNav: true}, '', `?option=${option}`)
updateUI()
}
function updateUI() {
const currentOption = new URL(window.location.href).searchParams.get('option')
document.getElementById('option').innerText = currentOption ? `Selected: ${currentOption}` : ''
document.getElementById('back').disabled = !(history.state && history.state.allowBackNav)
}
updateUI()
window.addEventListener('popstate', event => {
updateUI()
})
</script>
</body>
</html>