@virtualstate/app-history
Native JavaScript app-history implementation
Platforms
Test Coverage
Install
Snowpack
const { AppHistory } = await import("https://cdn.skypack.dev/@virtualstate/app-history");
Or
import { AppHistory } from "https://cdn.skypack.dev/@virtualstate/app-history";
npm / yarn / GitHub
npm i --save @virtualstate/app-history
Or
yarn add @virtualstate/app-history
Then
import { AppHistory } from "@virtualstate/app-history";
Navigation
import { AppHistory } from "./app-history";
const appHistory = new AppHistory();
// Set initial url
appHistory.navigate("/");
appHistory.navigate("/skipped");
// Use .finished to wait for the transition to complete
await appHistory.navigate("/awaited").finished;
Waiting for events
import { AppHistory } from "./app-history";
const appHistory = new AppHistory();
appHistory.addEventListener("navigate", async ({ destination }) => {
if (destination.url === "/disallow") {
throw new Error("No!");
}
});
await appHistory.navigate("/allowed").finished; // Resolves
await appHistory.navigate("/disallow").finished; // Rejects
Transitions
import { AppHistory } from "./app-history";
import { loadPhotoIntoCache } from "./cache";
const appHistory = new AppHistory();
appHistory.addEventListener("navigate", async ({ destination, transitionWhile }) => {
transitionWhile(loadPhotoIntoCache(destination.url));
});
State
import { AppHistory } from "./app-history";
const appHistory = new AppHistory();
appHistory.addEventListener("currentchange", () => {
console.log({ updatedState: appHistory.current?.getState() });
});
await appHistory.updateCurrent({
state: {
items: [
"first",
"second"
],
index: 0
}
}).finished;
await appHistory.updateCurrent({
state: {
...appHistory.current.getState(),
index: 1
}
}).finished;
Updating browser url
This is a pending development task. The below code will help visually update the window
This can be achieved various ways, but if your application completely utilises
the app history interface, then you can directly use pushState
to immediately
update the window’s url.
This does not take into account the browser’s native back/forward functionality, which would need to be investigated further.
import { AppHistory } from "./app-history";
const appHistory = new AppHistory();
const origin = typeof location === "undefined" ? "https://example.com" : location.origin;
appHistory.addEventListener("currentchange", () => {
const { current } = appHistory;
if (!current || !current.sameDocument) return;
const state = current.getState() ?? {};
const { pathname } = new URL(current.url, origin);
if (typeof window !== "undefined" && window.history) {
window.history.pushState(state, state.title, origin)
}
})