npm.io
0.7.13 • Published 1h ago

@real-router/hash-plugin

Licence
MIT
Version
0.7.13
Deps
2
Size
135 kB
Vulns
0
Weekly
0
Stars
6

@real-router/hash-plugin

npm npm downloads bundle size License: MIT

Hash-based routing plugin for Real-Router. Uses URL hash fragment (#/path) for navigation — no server configuration needed.

Works on static hosting (GitHub Pages, S3, Netlify) without redirect rules. Tradeoff: URLs include # (example.com/#!/users vs example.com/users).

Looking for clean URLs? Use @real-router/browser-plugin (History API).

Installation

npm install @real-router/hash-plugin

Peer dependency: @real-router/core

Quick Start

import { createRouter } from "@real-router/core";
import { hashPluginFactory } from "@real-router/hash-plugin";

const router = createRouter([
  { name: "home", path: "/" },
  { name: "users", path: "/users/:id" },
]);

router.usePlugin(hashPluginFactory());
await router.start(); // reads hash from browser location

Options

Option Type Default Description
hashPrefix string "" Prefix after # (e.g., "!"#!/path)
base string "" Base path before hash (e.g., "/app"/app#/path)
forceDeactivate boolean true Bypass canDeactivate guards on back/forward
router.usePlugin(hashPluginFactory({ hashPrefix: "!", base: "/app" }));

router.navigate("users", { id: "123" });
// URL: /app#!/users/123

Router Extensions

The plugin extends the router instance with three methods via extendRouter():

Method Returns Description
buildUrl(name, params?) string Build full URL with hash and prefix
matchUrl(url) State | undefined Parse hash URL to router state
replaceHistoryState(name, params?) void Update browser URL without navigation
router.buildUrl("users", { id: "123" });
// => "#!/users/123" (with hashPrefix "!")

router.matchUrl("https://example.com/#!/users/123");
// => { name: "users", params: { id: "123" }, path: "/users/123" }

// Update URL silently (no transition, no guards)
router.replaceHistoryState("users", { id: "456" });
buildUrl vs buildPath
router.buildPath("users", { id: 1 }); // "/users/1"       — core, no hash
router.buildUrl("users", { id: 1 }); // "#!/users/1"     — plugin, with hash prefix

Form Protection

Set forceDeactivate: false to respect canDeactivate guards on back/forward:

router.usePlugin(hashPluginFactory({ forceDeactivate: false }));

import { getLifecycleApi } from "@real-router/core/api";

const lifecycle = getLifecycleApi(router);
lifecycle.addDeactivateGuard(
  "checkout",
  (router, getDep) => (toState, fromState) => {
    return !hasUnsavedChanges(); // false blocks back/forward
  },
);

Limitations

Hash-plugin uses # as the route delimiter — URL fragments are structurally incompatible. The signatures of router.buildUrl(name, params, options?) and router.replaceHistoryState(name, params, options?) accept { hash } for typing parity with the other URL plugins, but at runtime the option is silently ignored and a one-time console.warn is emitted on the first invocation:

[@real-router/hash-plugin] `hash` option is ignored — `#` is reserved for the route delimiter.
Use browser-plugin or navigation-plugin for URL fragments.

state.context.url is not populated under hash-plugin (undefined at runtime). Hash-aware sources (useIsActiveRoute, <Link hash> active state) consequently return false for any non-undefined hash. Only one URL plugin (browser-plugin, navigation-plugin, or hash-plugin) may be installed per router instance.

If you need URL fragments for tab-style UIs or anchor scrolling, use @real-router/browser-plugin or @real-router/navigation-plugin instead — see the Hash Fragment Support wiki page.

SSR Support

SSR-safe — automatically detects the environment and falls back to no-ops:

router.usePlugin(hashPluginFactory());
router.buildUrl("home"); // returns hash path
router.matchUrl("/path"); // returns undefined

Advanced Exports

Export Description
Browser Browser interface type (from browser-env) — for custom browser implementations
isState Type guard to validate history state structure — (value: unknown) => value is State

Documentation

Full documentation: Wiki — hash-plugin

Package Description
@real-router/core Core router (required peer dependency)
@real-router/browser-plugin History API routing (clean URLs)
@real-router/react React integration

Contributing

See contributing guidelines for development setup and PR process.

License

MIT Oleg Ivanov

Keywords