Skip to content

Feature Request: Add matchRoutes Function #512

Description

@brtvcl

I’d like to request the addition of a matchRoutes function to Wouter. This function is available in react-router, and implementing it in Wouter should require minimal code.

Use Case

The matchRoutes function would allow users to find the active route based on the current location. This is particularly useful for handling layouts or route-based logic efficiently.

Example usage:

const routes = [
  { path: "/foo", component: <div>Foo</div> },
  { path: "/bar", component: <div>Bar</div>, layout: "red" },
];

const layouts = {
  default: ({ children }) => <div>{children}</div>,
  red: ({ children }) => <div style={{ backgroundColor: "red" }}>{children}</div>,
};

export default function App() {
  const [location] = useLocation();
  const activeRoute = matchRoutes(routes, location);
  const Layout = activeRoute?.layout ? layouts[activeRoute.layout] : layouts.default;

  return (
    <Layout>
      <Routes>
        {routes.map((route) => (
          <Route key={route.path} path={route.path} element={route.component} />
        ))}
      </Routes>
    </Layout>
  );
}

Example Implementation

This is the implementation I currently use in my project.
(~160 bytes, unminified)

import { parse } from "regexparam";

function matchRoutes(routes, location) {
  return routes.find((route) => {
    const regex = parse(route.path);
    return regex.pattern.test(location);
  });
}

Having this built into the library would prevent redundant loops (like in my example implementation) when matching routes, as Wouter itself already performs route matching internally.

Would love to hear your thoughts on this! Thanks for the awesome work on Wouter! 🚀

Activity

  1. max-mykhailenko commented on Apr 17, 2025

    @max-mykhailenko

    Or simply, it would be ideal to have something like matchPath without array handling — no need to support a specific array format.

  2. molefrog commented on Apr 18, 2025

    @molefrog
    Owner

    This is the implementation I currently use in my project. (~160 bytes, unminified)

    I am afraid the actual route matching in wouter is a bit more complex. However, we do export matchRoute function, could it be helpful?

    import { useRouter, useLocation, matchRoute } from "wouter";
    
    export function useMatchRoutes(routes) {
      const router = useRouter();
      const [location] = useLocation();
    
      // Go through each route and find the first match
      for (const route of routes) {
        const [matches, params] = matchRoute(
          router.parser,
          route.path,
          location,
          route.nest // optional, supports nested routes if needed
        );
    
        if (matches) {
          // Return both the matched route and the params
          return {
            route,
            params,
          };
        }
      }
    
      // Return null if no route matches
      return null;
    }
  3. max-mykhailenko commented on Apr 18, 2025

    @max-mykhailenko

    @molefrog thank you for your suggestion — it’s definitely interesting. However, it’s tied to the actual React component and can’t be executed outside of it.

    What I’m looking for is a standalone function that can run in a Node.js environment before rendering the React app. Its purpose is to determine which template is currently active and provide the necessary assets accordingly.

    Input: requestUrl, pathTemplate (e.g., users/:id)
    Output: Boolean

  4. brtvcl commented on Apr 22, 2025

    @brtvcl
    Author

    I am afraid the actual route matching in wouter is a bit more complex. However, we do export matchRoute function, could it be helpful?

    @molefrog It would work for my use case — but it doesn't offer any benefit to the thing I'm trying to avoid: having to loop through the routes myself to determine which one is active. If the solution is just a hook around matchRoutes, it doesn’t make much difference whether it's part of the library or implemented in my app.

    What I’m looking for is a way to optimize that loop so it only happens once within the library. That way, I can simply access the active route directly and use that to drive layout or other route-specific logic. Some way to access which route path is matched internally (without calculating again) with a hook or a function would be nice.

  5. piotr-cz commented on Aug 21, 2026

    @piotr-cz

    The suggested matchRoutes could just accept array of patterns.

    Overall it would simplify my current usage that involves using unofficial matchRoute function like so:

    import { Link, useLocation, useRouter, matchRoute } from 'wouter-preact'
    import clsx from 'clsx'
    
    /**
     * @type {preact.FunctionComponent<{
     *   path: string,
     *   name: string,
     *   activeFor: string[],
     * }>
     */
    export const NavLink = ({
      path,
      name,
      activeFor,
    }) = {
      const { parser } = useRouter()
      const [ currentPath ] = useLocation()
    
      let isActive = currentPath === path
    
      if (!isActive) {
        isActive = activeFor.some(route => matchRoute(parser, route, currentPath)[0]))
      }
    
      return (
        <li className={clsx({'uk-active': isActive})}>
          <Link href={path}>
            { name }
          </Link>
        </li>
      )
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions