I’m implementing a Single Page Application in vanilla JavaScript, and I’m stuck on history.pushState and history.replaceState issues.
This is my code:
HTML
<ul id="nav"></ul>
<div id="root"></div>
JS
const routes = {
"home": "Home",
"blog": "Blog",
"contact": "Contact"
};
for (var r in routes) nav.innerHTML += `<li data-id="${r}">${routes[r]}</li>`;
const load = page => {
page = page.replace("#", "");
nav.querySelector(".active")?.removeAttribute("class");
if (routes[page]) {
nav.querySelector(`[data-id="${page}"]`).className = "active";
fetch("pages/" + page + ".html")
.then(res => res.text())
.then(res => root.innerHTML = res);
history.pushState(null, null, location.pathname + "#" + page); // ISSUE #1
document.querySelector("title").innerText = routes[page];
} else {
history.replaceState(null, null, location.pathname + "#" + page); // ISSUE #2
location.href = "errors/404.html";
}
};
nav.onclick = e => {
if (e.target.tagName !== "LI") return;
load(e.target.dataset.id);
}
window.onpopstate = () => {
load(location.hash);
}
load(location.hash || "home");
ISSUE #1 – history.pushState(null, null, location.pathname + “#” + page);
When I click on the browser’s back button, it goes go back to one page only.
For instance: in the Home page, I click on Contact then on Blog, then I click on browser’s back button: it takes me back to Contact page, but if I click again (and again) on that button, it doesn’t take me back to Home page, stopping on Contact page.
ISSUE #2 – history.replaceState(null, null, location.pathname + “#” + page);
If the user writes a wrong URL (e.g. https://www.—.com/spa/#blogg), I want to delete that url from the browser’s history, before redirecting to 404 error page. But my code doesn’t do it: that URL is still in the browser’s history.
How can I fix those issues?
Any suggestions would be appreciated.