🧭 pushState() in JavaScript – Complete Tutorial

The History API allows JavaScript to manipulate the browser's session history without reloading the page. One of its most important methods is history.pushState(), which adds a new history entry and updates the URL.

πŸ“Œ What is pushState()?

history.pushState() adds a new entry to the browser's history stack. It changes the URL displayed in the address bar without refreshing the page, making it a key feature for building Single Page Applications (SPAs).

>>"pushState() changes the browser's URL without reloading the webpage."

πŸ’‘ Why Use pushState()?

  • ⚑ Build Single Page Applications (SPAs)
  • πŸ”„ Navigate between pages without reloading
  • πŸ”— Create shareable URLs
  • πŸ“– Improve browser Back and Forward navigation
  • 🎯 Maintain application state in the URL

πŸ›  Syntax

pushState() Syntax

history.pushState(state, unused, url);

πŸ“Š Parameters

ParameterDescription
stateA JavaScript object associated with the history entry.
unusedHistorically used for the page title. Pass an empty string ("").
urlThe new URL (must be from the same origin).

πŸš€ Basic Example

Change URL

history.pushState(
  {},
  "",
  "/about"
);

The browser URL becomes /about, but the page does not reload.

πŸ“¦ Storing State

You can associate data with the history entry using thestate object.

Store State

history.pushState(
  {
    page: "about",
    id: 101
  },
  "",
  "/about"
);

πŸ“– Reading State

Access the current history entry's state usinghistory.state.

Read State

console.log(history.state);

⬅️ Handling Back & Forward Buttons

When the user navigates using the browser's Back or Forward buttons, thepopstate event is triggered.

popstate Event

window.addEventListener(
  "popstate",
  (event) => {
    console.log(event.state);
  }
);

πŸ›  Complete Navigation Example

HTML

<button id="homeBtn">Home</button>
<button id="aboutBtn">About</button>

<h2 id="content">
  Home Page
</h2>

JavaScript

const content =
  document.getElementById("content");

document
  .getElementById("homeBtn")
  .onclick = () => {

    history.pushState(
      { page: "home" },
      "",
      "/home"
    );

    content.textContent =
      "Home Page";
};

document
  .getElementById("aboutBtn")
  .onclick = () => {

    history.pushState(
      { page: "about" },
      "",
      "/about"
    );

    content.textContent =
      "About Page";
};

window.addEventListener(
  "popstate",
  (event) => {

    if (event.state?.page === "home") {
      content.textContent =
        "Home Page";
    }

    if (event.state?.page === "about") {
      content.textContent =
        "About Page";
    }

  }
);

πŸ”„ pushState() vs replaceState()

Both methods update the browser's history, but they behave differently.

FeaturepushState()replaceState()
Creates New History Entryβœ… Yes❌ No
Changes URLβœ… Yesβœ… Yes
Back Button Returns to Previous URLβœ… Yes❌ No (the current entry is replaced)

πŸ“Š History Object Methods

MethodDescription
pushState()Adds a new history entry.
replaceState()Replaces the current history entry.
back()Moves back one page.
forward()Moves forward one page.
go()Moves through history by a specified number of entries.

πŸ§ͺ More Examples

Navigate Back

history.back()

history.back();

Navigate Forward

history.forward()

history.forward();

Go Two Pages Back

history.go()

history.go(-2);

Reload Current Entry

Reload Current Entry

history.go(0);

⚠️ Limitations

  • 🌐 The new URL must belong to the same origin (same protocol, domain, and port).
  • πŸ”„ pushState() changes only the URLβ€”it does not load new HTML automatically.
  • 🧠 You are responsible for updating the page content after changing the URL.
  • πŸ“„ Refreshing a pushed URL requires appropriate server-side routing if the URL doesn't map to a physical file.

Note

Modern frontend frameworks such as React Router, Vue Router, Angular Router, and SvelteKit use pushState() internally to implement client-side routing.

βœ… Best Practices

  • πŸ—ΊοΈ Keep the URL synchronized with the application's visible state.
  • πŸ“¦ Store only lightweight, serializable data in the state object.
  • ⬅️ Handle the popstate event so Back and Forward navigation works correctly.
  • πŸ”— Use meaningful URLs that users can bookmark and share.
  • πŸ›  Configure your server to support client-side routes on page refresh.

🎯 Summary

history.pushState() is a core feature of the History API that lets you add new history entries, update the browser's URL, and associate state with each entryβ€”all without reloading the page. Combined with thepopstate event, it enables smooth client-side navigation and forms the foundation of modern Single Page Applications.