https://github.com/virtualstate/navigation
Native JavaScript navigation [web api] implementation
https://github.com/virtualstate/navigation
browser deno navigation typescript
Last synced: about 2 months ago
JSON representation
Native JavaScript navigation [web api] implementation
- Host: GitHub
- URL: https://github.com/virtualstate/navigation
- Owner: virtualstate
- License: mit
- Created: 2021-12-20T10:37:25.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-03-23T03:13:54.000Z (3 months ago)
- Last Synced: 2025-04-12T23:38:47.196Z (about 2 months ago)
- Topics: browser, deno, navigation, typescript
- Language: TypeScript
- Homepage:
- Size: 1.05 MB
- Stars: 104
- Watchers: 5
- Forks: 7
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
- Code of conduct: CODE-OF-CONDUCT.md
Awesome Lists containing this project
README
# `@virtualstate/navigation`
Native JavaScript [navigation](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API) implementation
[//]: # (badges)
### Support
     
Test Coverage
    
[//]: # (badges)
## Install
npm / yarn / GitHub
- [Package Registry Link - GitHub](https://github.com/virtualstate/navigation/packages)
- [Package Registry Link - npm](https://www.npmjs.com/package/@virtualstate/navigation)```
npm i --save @virtualstate/navigation
```_Or_
```
yarn add @virtualstate/navigation
```Then
```typescript
import { Navigation } from "@virtualstate/navigation";
```Skypack
- [Package Registry Link - Skypack](https://www.skypack.dev/view/@virtualstate/navigation)
```typescript
const { Navigation } = await import("https://cdn.skypack.dev/@virtualstate/navigation");
```_Or_
```typescript
import { Navigation } from "https://cdn.skypack.dev/@virtualstate/navigation";
```importmap
[`importmap` documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap)
```html
{
"imports": {
"@virtualstate/navigation": "https://cdn.skypack.dev/@virtualstate/navigation"
}
}import { Navigation } from "@virtualstate/navigation"
```
## Usage
See the [MDN documentation for the Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API) for in depth information on usage.
Examples
## Navigation
```typescript
import { Navigation } from "@virtualstate/navigation";const navigation = new Navigation();
// Set initial url
navigation.navigate("/");navigation.navigate("/skipped");
// Use .finished to wait for the transition to complete
await navigation.navigate("/awaited").finished;```
## Waiting for events
```typescript
import { Navigation } from "@virtualstate/navigation";const navigation = new Navigation();
navigation.addEventListener("navigate", async ({ destination, preventDefault }) => {
if (new URL(destination.url).pathname === "/disallow") {
preventDefault();
}
});await navigation.navigate("/allowed").finished; // Resolves
await navigation.navigate("/disallow").finished; // Rejects```
## Transitions
```typescript
import { Navigation } from "@virtualstate/navigation";
import { loadPhotoIntoCache } from "./cache";const navigation = new Navigation();
navigation.addEventListener("navigate", async ({ destination, intercept }) => {
intercept({
async handler() {
await loadPhotoIntoCache(destination.url)
}
});
});
```## URLPattern
You can match `destination.url` using [`URLPattern`](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API)
```typescript
import {Navigation} from "@virtualstate/navigation";
import {URLPattern} from "urlpattern-polyfill";const navigation = new Navigation();
navigation.addEventListener("navigate", async ({destination, intercept}) => {
const pattern = new URLPattern({ pathname: "/books/:id" });
const match = pattern.exec(destination.url);
if (match) {
intercept({
handler: transition
});
}async function transition() {
console.log("load book", match.pathname.groups.id)
}
});navigation.navigate("/book/1");
```## State
```typescript
import { Navigation } from "@virtualstate/navigation";
const navigation = new Navigation();
navigation.addEventListener("currententrychange", () => {
console.log({ updatedState: navigation.currentEntry?.getState() });
});await navigation.updateCurrentEntry({
state: {
items: [
"first",
"second"
],
index: 0
}
}).finished;await navigation.updateCurrentEntry({
state: {
...navigation.currentEntry.getState(),
index: 1
}
}).finished;
```## Polyfill
If a global instance of the navigation API is not available, this will provide one, integrated into the History API if available.
```typescript
import "@virtualstate/navigation/polyfill";await window.navigation.navigate("/").finished;
// Or if within a window global scope, aka in a browser:
await navigation.navigate("/").finished;
```Polyfill Global Window Types
See [`@types/dom-navigation`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/dom-navigation/package.json) for a standardised type definition for the Navigation API
which can be utilised alongside this polyfill.```bash
yarn add --dev @types/dom-navigation
```This should then be included as a type in your `tsconfig.json`:
```json
{
"compilerOptions": {
"types": [
"dom-navigation"
]
}
}
```Polyfill Serializer
You may want to set a custom serializer to store state in history
The default serializer is [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)
In the past, a [structured clone like serializer](https://www.npmjs.com/package/@ungap/structured-clone) was used. This may be useful for you if
you're using native types rather than just JSON compatible values.An example of making use of a custom serializer with the polyfill:
```typescript
import { setSerializer } from "@virtualstate/navigation/polyfill";
import { serialize, deserialize } from "@ungap/structured-clone";setSerializer({
stringify(value) {
return serialize(value)
},
parse(value) {
return deserialize(value)
}
});
```### Polyfill Known Limitations
- [Navigation by setting window.location does not trigger navigate event](https://github.com/virtualstate/navigation/issues/27)
- [Normal page navigations are not intercepted (excluding navigation api & history made changes)](https://github.com/virtualstate/navigation/issues/26)Please [create a new GitHub Issue if you find further limitations](https://github.com/virtualstate/navigation/issues)