Under The Hood
frontend htmx HTMX 1.x / 2.x

hx-push-url: Browser History API Synchronization & Back/Forward Cache

Last updated
Prerequisites:
HTML5 History API (`pushState`, `popstate`)
HTMX hx-get
  • htmx
  • hx-push-url
  • history-api
  • pushState
  • navigation
  • url

Read at your depth

The practical view

`hx-push-url="true"` (or passing a specific path `hx-push-url="/contacts/1"`) updates the browser's address bar using `history.pushState()` when an HTMX request succeeds. HTMX snapshots the current DOM state into `localStorage` before swapping, so clicking the browser's Back button restores the previous view instantly without re-requesting the server.

The same idea in other frameworks

react equivalent
React Router `useNavigate()` pushing to `history` stack.

Legacy vs modern

Un-synced AJAX Partial vs Deep-Linkable hx-push-url

Without `hx-push-url`, the browser address bar stays frozen; with it, URLs update and back/forward navigation works.

before → after
Frozen URL AJAX Load
<button hx-get="/tab2" hx-target="#main">Tab 2</button> // ❌ URL remains /tab1, back button breaks
Deep-Linkable hx-push-url
<button hx-get="/tabs/settings" hx-push-url="true" hx-target="#main"> // ✅ NEW: Full URL sync

Interview gotchas

Context

Interviewers test your knowledge of HTMX server response control headers.

The mechanical answer

The server can send the **`HX-Push-Url: /new-url`** response header. This overrides client-side attributes and instructs HTMX to push `/new-url` onto the browser's history stack immediately upon swapping.

Trap

Sending `HX-Push-Url: false` explicitly prevents a URL from being pushed even if the client element had `hx-push-url="true"`.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.