@real-router/hash-plugin
v0.7.1
Published
Hash-based routing plugin for Real-Router
Downloads
1,225
Maintainers
Readme
@real-router/hash-plugin
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-pluginPeer 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 locationOptions
| 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/123Router 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 prefixForm 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
URL Fragments via <Link hash> / opts.hash
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 undefinedAdvanced 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
Related Packages
| 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.
