history npm package, it’s optimized specifically for TanStack Router’s needs.
Overview
The history API provides an abstraction over browser navigation that works across different environments (browser, hash-based, memory/SSR). It handles:- Navigation (push, replace, go, back, forward)
- Location tracking (pathname, search, hash, state)
- Navigation blocking/confirmation
- Subscription to location changes
History Types
TanStack Router supports three history implementations:Browser History
Uses the browser’s History API with standard URLs.- Clean URLs without hash fragments
- Full pathname support
- Better SEO
- Standard browser behavior
index.html for all routes.
Hash History
Uses hash-based routing for static hosting environments.- Deploying to static hosts without URL rewriting (GitHub Pages, S3)
- Server configuration is not possible
- Maintaining compatibility with older systems
Memory History
Uses in-memory storage for non-browser environments.- Server-side rendering (SSR)
- Testing environments
- Non-DOM platforms (React Native, Electron)
Creating a Router with History
Pass a history instance to the router:History API
All history implementations expose a common interface:Navigation Methods
push
Navigate to a new location and add it to the history stack:replace
Replace the current location without adding to the stack:go
Navigate by a relative offset:back
Navigate to the previous entry:forward
Navigate to the next entry:Location Properties
Access current location information:Subscriptions
Listen to location changes:'PUSH'- New entry added'REPLACE'- Current entry replaced'BACK'- Navigated backward'FORWARD'- Navigated forward'GO'- Navigated by offset
History Throttling
TanStack Router implements history throttling to prevent excessive calls to the browser’s History API.Why Throttling?
Some browsers ignore rapidpushState/replaceState calls. Throttling ensures:
- Consistent behavior across browsers
- Prevention of lost state updates
- Optimized performance for rapid navigation
How It Works
Updates are queued in a microtask and flushed asynchronously:Forcing Immediate Flush
If you need the URL to be immediately updated:Navigation Blocking
Block navigation to show confirmation dialogs:Blocker Function
The blocker function receives:currentLocation: Where the user currently isnextLocation: Where they’re trying to goaction: The type of navigation (PUSH, REPLACE, etc.)
true to allow navigation, false to block it.
beforeunload Event
WhenenableBeforeUnload is true, the browser shows a confirmation dialog when:
- Closing the tab/window
- Navigating away from your site
- Refreshing the page
Multiple Blockers
You can register multiple blockers:false, navigation is cancelled.
Custom History Options
Browser History Options
Hash History Options
Memory History Options
History State
Pass custom state with navigation:State Structure
TanStack Router adds internal state properties:__TSR to prevent conflicts.
Creating Href URLs
Generate URLs for use in links:createHref logic.
Server-Side Rendering
For SSR, use memory history:Testing with History
Use memory history for predictable tests:History Length
Get the total number of entries:Cleanup
Destroy the history instance to remove event listeners:Best Practices
- Use browser history unless you have a specific reason not to
- Configure server redirects to support browser history
- Use memory history for SSR and testing
- Avoid direct history manipulation - use router navigation methods instead
- Cleanup blockers when components unmount
- Test navigation using memory history
- Prefer router.navigate() over history methods for type safety
Migration from React Router
If you’re coming from React Router:| React Router | TanStack Router |
|---|---|
createBrowserRouter + BrowserRouter | createBrowserHistory |
createHashRouter + HashRouter | createHashHistory |
createMemoryRouter + MemoryRouter | createMemoryHistory |
history.push(path) | history.push(path) |
history.replace(path) | history.replace(path) |
history.goBack() | history.back() |
history.goForward() | history.forward() |
history.listen() | history.subscribe() |