history
history
is a JavaScript library that lets you easily manage session history anywhere JavaScript runs. history
abstracts away the differences in various environments and provides a minimal API that lets you manage the history stack, navigate, confirm navigation, and persist state between sessions.
Installation
Using npm:
$ npm install --save history
Then with a module bundler like webpack, use as you would anything else:
import { createBrowserHistory } from 'history';
var createBrowserHistory = require('history').createBrowserHistory;
The UMD build is also available on unpkg:
<script src="https://unpkg.com/history"></script>
You can find the library on window.History
.
Usage
history
provides 3 different methods for creating a history
object, depending on your environment.
createBrowserHistory
is for use in modern web browsers that support the HTML5 history API (see cross-browser compatibility)createMemoryHistory
is used as a reference implementation and may also be used in non-DOM environments, like React Native or testscreateHashHistory
is for use in legacy web browsers
Depending on the method you want to use to keep track of history, you'll import
(or require
) one of these methods directly from the package root (i.e. history/createBrowserHistory
). The remainder of this document uses the term createHistory
to refer to any of these implementations.
Basic usage looks like this:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
const location = history.location;
const unlisten = history.listen((location, action) => {
console.log(action, location.pathname, location.state);
});
history.push('/home', { some: 'state' });
unlisten();
The options that each create
method takes, along with its default values, are:
createBrowserHistory({
basename: '',
forceRefresh: false,
keyLength: 6,
getUserConfirmation: (message, callback) => callback(window.confirm(message))
});
createMemoryHistory({
initialEntries: ['/'],
initialIndex: 0,
keyLength: 6,
getUserConfirmation: null
});
createHashHistory({
basename: '',
hashType: 'slash',
getUserConfirmation: (message, callback) => callback(window.confirm(message))
});
Properties
Each history
object has the following properties:
history.length
- The number of entries in the history stackhistory.location
- The current location (see below)history.action
- The current navigation action (see below)
Additionally, createMemoryHistory
provides history.index
and history.entries
properties that let you inspect the history stack.
Listening
You can listen for changes to the current location using history.listen
:
history.listen((location, action) => {
console.log(
`The current URL is ${location.pathname}${location.search}${location.hash}`
);
console.log(`The last navigation action was ${action}`);
});
The location
object implements a subset of the window.location
interface, including:
location.pathname
- The path of the URLlocation.search
- The URL query stringlocation.hash
- The URL hash fragment
Locations may also have the following properties:
location.state
- Some extra state for this location that does not reside in the URL (supported in createBrowserHistory
and createMemoryHistory
)location.key
- A unique string representing this location (supported in createBrowserHistory
and createMemoryHistory
)
The action
is one of PUSH
, REPLACE
, or POP
depending on how the user got to the current URL.
Cleaning up
When you attach a listener using history.listen
, it returns a function that can be used to remove the listener, which can then be invoked in cleanup logic:
const unlisten = history.listen(myListener);
unlisten();
Navigation
history
objects may be used to programmatically change the current location using the following methods:
history.push(path, [state])
history.replace(path, [state])
history.go(n)
history.goBack()
history.goForward()
history.canGo(n)
(only in createMemoryHistory
)
When using push
or replace
you can either specify both the URL path and state as separate arguments or include everything in a single location-like object as the first argument.
- A URL path or
- A location-like object with
{ pathname, search, hash, state }
history.push('/home');
history.push('/home?the=query', { some: 'state' });
history.push({
pathname: '/home',
search: '?the=query',
state: { some: 'state' }
});
history.go(-1);
history.goBack();
Note: Location state is only supported in createBrowserHistory
and createMemoryHistory
.
Blocking Transitions
history
lets you register a prompt message that will be shown to the user before location listeners are notified. This allows you to make sure the user wants to leave the current page before they navigate away.
const unblock = history.block('Are you sure you want to leave this page?');
history.block((location, action) => {
if (input.value !== '') return 'Are you sure you want to leave this page?';
});
unblock();
Note: You'll need to provide a getUserConfirmation
function to use this feature with createMemoryHistory
(see below).
Customizing the Confirm Dialog
By default, window.confirm
is used to show prompt messages to the user. If you need to override this behavior (or if you're using createMemoryHistory
, which doesn't assume a DOM environment), provide a getUserConfirmation
function when you create your history object.
const history = createHistory({
getUserConfirmation(message, callback) {
}
});
Using a Base URL
If all the URLs in your app are relative to some other "base" URL, use the basename
option. This option transparently adds the given string to the front of all URLs you use.
const history = createHistory({
basename: '/the/base'
});
history.listen(location => {
console.log(location.pathname);
});
history.push('/home');
Note: basename
is not suppported in createMemoryHistory
.
Forcing Full Page Refreshes in createBrowserHistory
By default createBrowserHistory
uses HTML5 pushState
and replaceState
to prevent reloading the entire page from the server while navigating around. If instead you would like to reload as the URL changes, use the forceRefresh
option.
const history = createBrowserHistory({
forceRefresh: true
});
Modifying the Hash Type in createHashHistory
By default createHashHistory
uses a leading slash in hash-based URLs. You can use the hashType
option to use a different hash formatting.
const history = createHashHistory({
hashType: 'slash'
});
history.push('/home');
const history = createHashHistory({
hashType: 'noslash'
});
history.push('/home');
const history = createHashHistory({
hashType: 'hashbang'
});
history.push('/home');
About
history
is developed and maintained by React Training. If
you're interested in learning more about what React can do for your company, please
get in touch!
Thanks
A big thank-you to BrowserStack for providing the infrastructure that allows us to run our build in real browsers.
Also, thanks to Dan Shaw for letting us use the history
npm package name. Thanks Dan!