1.0.1-alpha.206 • Published 8 months ago

@virtualstate/navigation v1.0.1-alpha.206

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

@virtualstate/navigation

Native JavaScript navigation implementation

Support

Node.js supported Deno supported Bun supported Chromium supported Webkit supported Firefox supported

Web Platform Tests 140/277 92.86%25 lines covered 92.86%25 statements covered 83.11%25 functions covered 83.02%25 branches covered

Install

npm i --save @virtualstate/navigation

Or

yarn add @virtualstate/navigation

Then

import { Navigation } from "@virtualstate/navigation";
const { Navigation } = await import("https://cdn.skypack.dev/@virtualstate/navigation");

Or

import { Navigation } from "https://cdn.skypack.dev/@virtualstate/navigation";

importmap documentation

<script type="importmap">
    {  
        "imports": {
            "@virtualstate/navigation": "https://cdn.skypack.dev/@virtualstate/navigation"
        }
    }
</script>
<script type="module">
    import { Navigation } from "@virtualstate/navigation"
</script>

Usage

See the MDN documentation for the Navigation API for in depth information on usage.

Navigation

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

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

import { Navigation } from "@virtualstate/navigation";
import { loadPhotoIntoCache } from "./cache";

const navigation = new Navigation();

navigation.addEventListener("navigate", async ({ destination, intercept }) => {
    intercept(loadPhotoIntoCache(destination.url));
});

URLPattern

You can match destination.url using URLPattern

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(transition());
    }

    async function transition() {
        console.log("load book", match.pathname.groups.id)
    }
});

navigation.navigate("/book/1");

State

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.

import "@virtualstate/navigation/polyfill";

await window.navigation.navigate("/").finished;

// Or if within a window global scope, aka in a browser:
await navigation.navigate("/").finished;

See @types/dom-navigation for a standardised type definition for the Navigation API which can be utilised alongside this polyfill.

yarn add --dev @types/dom-navigation

This should then be included as a type in your tsconfig.json:

{
  "compilerOptions": {
    "types": [
      "dom-navigation"
    ]
  }
}

You may want to set a custom serializer to store state in history

The default serializer is JSON

In the past, a structured clone like serializer 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:

import { setSerializer } from "@virtualstate/navigation/polyfill";
import { serialize, deserialize } from "@ungap/structured-clone";

setSerializer({
    stringify(value) {
        return serialize(value)
    },
    parse(value) {
        return deserialize(value)
    }
});

What's Changed

  • (1.0.1-alpha.206) Updated default serializer for polyfill to JSON #35
1.0.1-alpha.206

8 months ago

1.0.1-alpha.204

11 months ago

1.0.1-alpha.205

11 months ago

1.0.1-alpha.203

1 year ago

1.0.1-alpha.202

1 year ago

1.0.1-alpha.201

1 year ago

1.0.1-alpha.200

1 year ago

1.0.1-alpha.199

2 years ago

1.0.1-alpha.197

2 years ago

1.0.1-alpha.198

2 years ago

1.0.1-alpha.196

2 years ago

1.0.1-alpha.195

2 years ago

1.0.1-alpha.193

2 years ago

1.0.1-alpha.191

2 years ago

1.0.1-alpha.192

2 years ago

1.0.1-alpha.190

2 years ago

1.0.1-alpha.188

2 years ago

1.0.1-alpha.189

2 years ago

1.0.1-alpha.186

2 years ago

1.0.1-alpha.187

2 years ago

1.0.1-alpha.184

2 years ago

1.0.1-alpha.185

2 years ago

1.0.1-alpha.182

2 years ago

1.0.1-alpha.183

2 years ago

1.0.1-alpha.180

2 years ago

1.0.1-alpha.181

2 years ago

1.0.1-alpha.179

2 years ago

1.0.1-alpha.178

2 years ago

1.0.1-alpha.137

3 years ago

1.0.1-alpha.138

3 years ago

1.0.1-alpha.135

3 years ago

1.0.1-alpha.136

3 years ago

1.0.1-alpha.177

3 years ago

1.0.1-alpha.133

3 years ago

1.0.1-alpha.175

3 years ago

1.0.1-alpha.131

3 years ago

1.0.1-alpha.176

3 years ago

1.0.1-alpha.132

3 years ago

1.0.1-alpha.173

3 years ago

1.0.1-alpha.174

3 years ago

1.0.1-alpha.130

3 years ago

1.0.1-alpha.171

3 years ago

1.0.1-alpha.172

3 years ago

1.0.1-alpha.170

3 years ago

1.0.1-alpha.139

3 years ago

1.0.1-alpha.126

3 years ago

1.0.1-alpha.127

3 years ago

1.0.1-alpha.168

3 years ago

1.0.1-alpha.124

3 years ago

1.0.1-alpha.169

3 years ago

1.0.1-alpha.125

3 years ago

1.0.1-alpha.166

3 years ago

1.0.1-alpha.122

3 years ago

1.0.1-alpha.123

3 years ago

1.0.1-alpha.164

3 years ago

1.0.1-alpha.120

3 years ago

1.0.1-alpha.165

3 years ago

1.0.1-alpha.121

3 years ago

1.0.1-alpha.162

3 years ago

1.0.1-alpha.163

3 years ago

1.0.1-alpha.160

3 years ago

1.0.1-alpha.161

3 years ago

1.0.1-alpha.128

3 years ago

1.0.1-alpha.129

3 years ago

1.0.1-alpha.159

3 years ago

1.0.1-alpha.115

3 years ago

1.0.1-alpha.116

3 years ago

1.0.1-alpha.157

3 years ago

1.0.1-alpha.113

3 years ago

1.0.1-alpha.158

3 years ago

1.0.1-alpha.155

3 years ago

1.0.1-alpha.111

3 years ago

1.0.1-alpha.156

3 years ago

1.0.1-alpha.112

3 years ago

1.0.1-alpha.153

3 years ago

1.0.1-alpha.154

3 years ago

1.0.1-alpha.110

3 years ago

1.0.1-alpha.151

3 years ago

1.0.1-alpha.152

3 years ago

1.0.1-alpha.150

3 years ago

1.0.1-alpha.119

3 years ago

1.0.1-alpha.117

3 years ago

1.0.1-alpha.118

3 years ago

1.0.1-alpha.148

3 years ago

1.0.1-alpha.149

3 years ago

1.0.1-alpha.146

3 years ago

1.0.1-alpha.147

3 years ago

1.0.1-alpha.144

3 years ago

1.0.1-alpha.145

3 years ago

1.0.1-alpha.142

3 years ago

1.0.1-alpha.143

3 years ago

1.0.1-alpha.140

3 years ago

1.0.1-alpha.141

3 years ago

1.0.1-alpha.104

3 years ago

1.0.1-alpha.105

3 years ago

1.0.1-alpha.102

3 years ago

1.0.1-alpha.103

3 years ago

1.0.1-alpha.100

3 years ago

1.0.1-alpha.101

3 years ago

1.0.1-alpha.97

3 years ago

1.0.1-alpha.96

3 years ago

1.0.1-alpha.108

3 years ago

1.0.1-alpha.109

3 years ago

1.0.1-alpha.106

3 years ago

1.0.1-alpha.107

3 years ago

1.0.1-alpha.95

3 years ago

1.0.1-alpha.94

3 years ago

1.0.1-alpha.93

3 years ago