Search code examples
javascriptreactjsreact-routerreact-router-dom

NavLink isActive with multiple paths to same component


I have two paths ("/" and "/home") that render the same component:

const router = createBrowserRouter([
  {
    path: "/",
    element: <ContentWrapper />,
    errorElement: <p>404</p>,
    children: [
      { path: "", element: <Home /> },
      { path: "home", element: <Home /> },
    ]
  }
])

Is it possible to get isActive=true from NavLink for both exaple.com and exaple.com/home?

<div>
  <NavLink to="/home" className={({ isActive }) => ( isActive ? ... : ...>
    Home
  </NavLink>
  <NavLink to="/projects" className={({ isActive }) => ( isActive ? ... : ...>
    Projects
  </NavLink>
  <NavLink to="/about" className={({ isActive }) => ( isActive ? ... : ...>
    About
  </NavLink>
</div>

Right now <Home /> component gets rendered in both "/" and "/home" paths, the only problem is the menu, Home NavLink has active CSS only when the path is "/home".

If it is not possible, can I always redirect from "/" to "/home" from the BrowserRouter (without using a custom empty component with an effect to call redirect function)?

I'd like to give a simple link like "https://example.com" and not "https://exaple.com/home", but I'd like to keep the "/home" path.


Solution

  • I don't think you'll get what you want without creating your own custom path matching logic. A "/home" path will match any "/home/*" path, but exclude "/" from matching, and using path "/" will match any path, and using "/" with the end prop will match "/" exactly and exclude "/home".

    If it is not possible, can I always redirect from "/" to "/home" from the BrowserRouter (without using a custom empty component with an effect to call redirect function)?

    Yes, this is possible. Redirecting from "/" to "/home", or vice versa, so there is only one route rendering Home so the link can match is my suggestion.

    Example:

    const router = createBrowserRouter([
      {
        path: "/",
        element: <ContentWrapper />,
        errorElement: <p>404</p>,
        children: [
          { index: true, element: <Navigate to="/home" replace /> },
          { path: "home", element: <Home /> },
        ]
      }
    ]);