Have ideas to improve npm?Join in the discussion! »

    TypeScript icon, indicating that this package has built-in type declarations

    0.2.2 • Public • Published


    URLObserver observes URL changes in web browsers

    Buy Me A Coffee tippin.me Follow me

    Version MIT License

    Downloads Total downloads Packagephobia Bundlephobia

    ci Dependency Status codecov

    codebeat badge Language grade: JavaScript Code of Conduct

    Inspired by PerformanceObserver but for observing history on browsers.

    Table of contents



    # Install via NPM
    $ npm install url-observer


    import 'url-observer';
    const observer = new URLObserver((list, observer) => {
      for (const entry of list.getEntries()) {
        /** Process entry for each URL update */ 
    const routes = [
    const options = {
      dwellTime: 2e3, /** Default dwellTime. Set -1 to always push new URL */
      debug: false, /** Set to enable debug mode. This exposes hidden `routes` property. */
      matcherCallback() {
         * Override how route matching works internally.
         * By default, ES2018's RegExp named capture groups are used.
    /** Call .observe() to start observing history */
    observe.observe(routes, options);
    /** Call .add() to add new route or before route handler to existing registered route */
      handleEvent: () => {
        /** Do anything before route changes. Return true to navigate to new route. */
        return true;
      pathRegExp: routes[0],
       * A scoped route handler enables multiple before route handler to be registered to the
       * same route. E.g.
       * A .data-scope property or `data-scope` attribute can be set in an anchor tag so that URLObserver
       * knows which before route handler it needs to trigger before navigating to a new URL.
       * When .data-scope (or `data-scope`) is an empty string, it defaults to ':default', which is the 
       * default scope value when registering a route unless specified.
       * 1. <a href="/test/123">/test/456</a>
       *    - No before route handler will be triggered on link click as it is not a scoped link.
       * 2. <a href="/test/123" data-scope>/test/123</a>
       *    - Only before route handler registered to ':default' scope will be triggered.
       * 3. <a href="/test/123" data-scope="456">/test/456</a>
       *    - Only before route handler registered to '456' scope will be triggered.
      scope: '',
    /** Dynamically add new route without before route handler */
    observer.add({ pathRegExp: /^\/test2$/i });
    /** Call .disconnect() to stop observing history */
    /** Call .match() to determine if current URL is being observed by URLObserver */
    const {
      /** Return true for a matched route */
       * Return URL parameters after matching the route RegExp with current URL. E.g.
       * 1. /^\/test/i
       *    - This does not output any matches
       * 2. /^\/test\/(?<test>[^\/]+)$/i
       *    - This matches URL like '/test/123' and returns { test: 123  }. However, this requires
       *      ES2018's RegExp named capture groups to work as expected.
    } = observer.match();
    /** Remove a route from the observer */
    /** Remove a before route handler from an observing route */
    observer.remove(routes[1], '456');
    /** Return the history entries */
    /** Async-ly call .updateHistory to manually update to new URL */
    await observer.updateHistory('/test/789');
     * Async-ly call .updateHistory to manually update to new URL and trigger before route handler
     * with defined scope value.
    await observer.updateHistory('/test/456', '456');

    API References


    Code of Conduct

    Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.


    MIT License © Rong Sen Ng


    npm i url-observer

    DownloadsWeekly Downloads






    Unpacked Size

    58.9 kB

    Total Files


    Last publish


    • avatar