Search code examples
reactjstypescriptreact-routerreact-router-dom

React redirect with parameters


We are in the process of migrating from an old system written in angularJS to a new system, the problem however is that we have some url's that are specifically written with a double slash ie "/#/work/customerDetails//:id" now these urls do not work with useResolvedPath, as its being normalized and therefore the double slash removed. So we want to put a redirect in place, which looks for the old urls (for the bits of code that still uses them) and redirects them to the new url (replacing the double slash with a single slash, so that the useResolvedPath will work correctly).

We currently use a simple hash router in our react app (which is part of a single-spa microservice), however, every option that I can think of to use in the redirect does not seem to work:

const router = createHashRouter(
  createRoutesFromElements(
    <Route path="work" element={<Root />}>
      <Route
        path="customerDetails//:id"
        element={<Navigate to="/#/work/customerDetails/:id" />}
      />
      <Route
        path="customerDetails/:id"
        element={<SiteAccount />}
      >
        {siteAccountRoutes}
      </Route>
    </Route>
  )
);

export default router

Solution

  • You are trying to redirect to a nested hashroute and the new target won't have the id path parameter of the current route "forwarded" to it.

    Create a small component that can sniff the current route params, and apply them to a redirection target path.

    Example:

    import {
      Navigate,
      useParams,
      generatePath
    } from "react-router-dom";
    
    const Redirect = ({ to }) => {
      const params = useParams();
      return <Navigate to={generatePath(to, params)} replace />;
    };
    

    Render Redirect with a new target path to the sibling "/work/customerDetails/:id" route.

    <Route path="work" element={<Root />}>
      <Route
        path="customerDetails//:id"
        element={<Redirect to="../customerDetails/:id" />}
      />
      <Route path="customerDetails/:id" element={<SiteAccount />}>
        {siteAccountRoutes}
      </Route>
    </Route>