npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pwabucket/pwa-router

v0.0.16

Published

Hooks and utilities for client-side routing in React applications, designed for Progressive Web Apps (PWAs).

Readme

@pwabucket/pwa-router

Hooks and utilities for client-side routing in React applications, designed for Progressive Web Apps (PWAs). Built on top of React Router.

Installation

# npm
npm install @pwabucket/pwa-router

# pnpm
pnpm add @pwabucket/pwa-router

Peer Dependencies

  • react ^18 || ^19
  • react-router ^7

Setup

Wrap your application with PWARoutingProvider inside a React Router context. The provider manages internal history tracking needed by the routing hooks.

// main.tsx
import App from "./App.tsx";
import { BrowserRouter } from "react-router";
import { PWARoutingProvider } from "@pwabucket/pwa-router";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <BrowserRouter>
      <PWARoutingProvider>
        <App />
      </PWARoutingProvider>
    </BrowserRouter>
  </StrictMode>,
);

// App.tsx
import { usePWARouting } from "@pwabucket/pwa-router";
import { Routes, Route } from "react-router";

function App() {
  const { resolvedLocation } = usePWARouting();
  
  return (
    <Routes location={resolvedLocation}>
        {/* your routes */}
    </Routes>
  );
}

Hooks

usePWARouting

Access the PWARoutingContext value, which exposes the resolved location.

import { usePWARouting } from "@pwabucket/pwa-router";

const { resolvedLocation } = usePWARouting();

Returns: PWARoutingContextValue{ resolvedLocation: Location }


useLocationState

Manage state tied to the current location entry. When the value is cleared (undefined), it navigates back automatically.

import { useLocationState } from "@pwabucket/pwa-router";

const [value, setValue] = useLocationState("myKey", "default");

// Set a new value (pushes to history)
setValue("new value");

// Clear value (navigates back)
setValue(undefined);

// Clear value and navigate back to a specific history index
setValue(undefined, {}, historyIndex);

Parameters:

| Param | Type | Description | | --- | --- | --- | | key | string | State key in location.state | | defaultValue | T | Fallback when the key is not present |

Returns: [T, (value?: T, options?: NavigateOptions, index?: number) => void]

  • When value is provided, navigates to the current location with the new state value.
  • When value is undefined and index is provided, calculates a history delta and navigates back to that entry.
  • When value is undefined and no index, navigates back one entry (or to "/" if there is no prior history).

useLocationToggle

A convenience wrapper around useLocationState for boolean toggle patterns (e.g. modals, drawers, sheets). Internally uses useLocationIndex to navigate back to the correct history entry when closing.

import { useLocationToggle } from "@pwabucket/pwa-router";

const [isOpen, toggle] = useLocationToggle("modal");

// Open
toggle(true);

// Close (navigates back)
toggle(false);

Parameters:

| Param | Type | Description | | --- | --- | --- | | key | string | State key in location.state | | indexKey | string? | Optional key for index tracking (see useLocationIndex) |

Returns: [boolean, (status: boolean, options?: NavigateOptions) => void]


useLocationIndex

Reads the saved history index for a given key from location.state. The index is stored under the key __router_index_<key>. Used internally by useLocationToggle to navigate back to the correct entry.

import { useLocationIndex } from "@pwabucket/pwa-router";

const index = useLocationIndex("modal");

Parameters:

| Param | Type | Description | | --- | --- | --- | | key | string? | The index tracking key |

Returns: number | undefined


useLocationIndexUpdater

Stamps the current history.length onto location.state (under __router_index_<key>) so that useLocationToggle can navigate back to the correct entry when closing. Call this in a layout or page component that serves as a "base" for toggled UI.

import { useLocationIndexUpdater } from "@pwabucket/pwa-router";

function Layout() {
  useLocationIndexUpdater("modal");
  // ...
}

Parameters:

| Param | Type | Description | | --- | --- | --- | | key | string | The index tracking key |


useNavigateBack

Returns a callback that navigates back in history. If there is no prior history entry (i.e. the user landed directly on the page), it navigates to a root path instead.

import { useNavigateBack } from "@pwabucket/pwa-router";

function Header() {
  const navigateBack = useNavigateBack();

  return <button onClick={() => navigateBack()}>Back</button>;
}

Parameters:

| Param | Type | Description | | --- | --- | --- | | root | string? | Fallback path when there is no history to go back to (default: "/") |

Returns: (options?: NavigateOptions) => void

Types

The following types are exported for convenience:

  • PWARoutingContextValue{ resolvedLocation: Location }
  • UseLocationStateReturn<T>[T, (value?: T, options?: NavigateOptions, index?: number) => void]
  • UseLocationToggleReturn[boolean, (status: boolean, options?: NavigateOptions) => void]

License

MIT