app-history is an extension to history designed for use in progressive web apps. The API is a superset of history so you can use it as a drop-in replacement in react-router for example. TypeScript definitions are included.
The primary objective for app-history is to help developers implement back/home-buttons in progressive web apps.
When building a progressive web app you probably want to include a back-button in the user interface to support navigation in standalone mode (without browser chrome).
blah blah blah back button options
Another useful feature provided by app-history is the ability to clear the history forward stack.
blah blah blah wizard/stepper options
Using NPM and a bundler (like webpack):
npm install --save app-history
Then create an App History object in your code like this:
import { createAppHistory } from "app-history";
const history = createAppHistory();
await history.init();Use it with react-router something like this:
import * as React from "react";
import { render } from "react-dom";
import { Router } from "react-router";
import { createAppHistory } from "app-history";
import { App } from "./App"; // Your app root component
// Create App History object (extending Browser History)
const history = createAppHistory();
await history.init();
// Create a <div> that will host the App component
const root = document.createElement("div");
document.body.appendChild(root);
// Tell React to render our app. Wrap it inside a Router component
// which is configured to use the App History object.
render(
<Router history={history}>
<App/>
</Router>,
root
);Alternatively, you can load it directly from the UNPKG CDN using vanilla HTML and JavaScript:
<script src="https://unpkg.com/history/umd/history.min.js"></script>
<script src="https://unpkg.com/app-history/dist/app-history.js"></script>Notice that you'll have to load the history UMD package too
Then create an App History object in your code like this:
const history = AppHistory.createAppHistory({ provider: History });
history.init().then(function () {
// do stuff
});app-history is built for ES5 but require support for Promise objects. To ensure compatibility you may want to load a Promise polyfill too.
TODO
TODO
TODO
Blah blah. Why it's needed and Implicit if you wish
The depth property of an app-history object lets you know how deep into the app you've gone, and thereby how far back you can go and still remain inside the current app session:
console.log("We can navigate back ", history.depth, " entry/entries and still be in this app session");An history object lets you listen on location changes and conditionally block transitions, using listen and block respectively.
If you which to temporarily pause notifications and prompts you can do:
const resume = history.suppress();
// this will not notify listeners or invoke block prompt
history.pushState("foo", "bar");
// resume normal processing when you're done with the secret stuff
resume();Or using a callback action:
history.suppressWhile(() => {
// code in this callback won't notify listeners or invoke block prompt
});suppressWhile returns a Promise object and will await a Promise object returned by the callback function.
You can at any time determine whether notifications and prompts are being suppressed:
console.log("Suppression is ", history.isSuppressed ? "active" : "inactive");app-history return promises from all methods that may trigger a location change. These promises are resolved when the new location has been applied, or rejected in case the change is blocked.
This includes the following methods from history:
gogoBackgoForwardpushreplace
And these extension methods:
cutfindLastgoHomeinitsuppressWhilewhenIdle
You can determine whether app-history is currently processing an async operation by reading the isBusy property:
console.log("App history is ", history.isBusy ? "busy" : "idle");TODO
createAppHistory will, by default, create a new browser history using createBrowserHistory from the history package.
You can instruct app-history to use createMemoryHistory (also from the history package) instead, which is helpful when testing your code in a non-browser environment:
const history = createAppHistory({
mode: "memory"
});If you want to provide another underlying history object you can do so (however, it is strongly recommended that you only access the underlying history object via the newly returned app-history extension to avoid confusion):
const history = createAppHistory({
provider: myHistoryObjectProvider
});The supplied provider object must declare a function named createBrowserHistory when mode is omitted or set to "browser", or a function named createMemoryHistory when mode is set to "memory".
app-history will invoke the provided function with a configuration object containing a getUserConfirmation function, no matter whether such a configuration function was passed to createAppHistory or not.
app-history is based on HTML5 History API state objects. So make sure that the underlying history object has support for that.
By default, app-history will (just like history) use window.confirm to display a prompt when navigation is blocked. You can provide a custom prompt to createAppHistory:
const history = createAppHistory({
getUserConfirmation(message, callback) {
callback(window.confirm(message));
}
});Please refer to the history package for details.
app-history will internally store some meta information in HTML5 History API state objects. One piece of information is a cache of app-specific paths in the history back stack. By default, the cache is limited to 20 entries. If you want to change this you can do so:
const history = createAppHistory({
cacheLimit: 5 // Keep at most five paths cached in my state objects
});If you want to disable caching:
const history = createAppHistory({
cacheLimit: 0 // No cached paths in my state objects
});Or if you want to let the cache grow indefinately:
const history = createAppHistory({
cacheLimit: -1 // Cache 'em all!
});You can read the currect cache limit like this:
console.log("The app history cache limit is set to: ", history.cacheLimit);