react router v6:how to set a route with absolute path?

Viewed 95

if click the NavLink, go to /search, and Search will be displayed

how to solve this in router v6? help please!!!

function App() {
  return (
    <div>
      <BrowserRouter basename={'/index'}>
        <Routes>
          <Route path={'/A/*'} element={<Home/>} />
          <Route path={'/search/*'} element={<Home />} />
        </Routes>
      </BrowserRouter>

    </div>
  );
}

function Home() {
  return (
    <div>
      <div>Home</div>
      <NavLink to={'/search'}>Search</NavLink>
      <Routes>
        <Route path={'/search'} element={<Search/>}/>
        <Route path={'/B/B1/show'} element={<Show/>}/>
      </Routes>
      <div>Footer</div>
    </div>
  )
}
2 Answers

The code you've shared already is using routes with absolute paths. The confusion seems to be with how links can use relative or absolute paths. The difference between relative and absolute paths is trivially simple: absolute paths start with a leading slash "/" character while relative paths do not.

The NavLink component rendering a to="/search" prop is linking an absolute path to "/search" and the result is that the URL is updated to "/search" and the Home component continues to remain mounted and no other components or routes are matched and rendered.

If the goal is to click the <NavLink to="search">Search</NavLink> link and navigate to "/A/search" then use a relative link path. Remove the leading "/" from the link path target.

function Home() {
  return (
    <div>
      <div>Home</div>
      <NavLink to="search">Search</NavLink> // link to "./search"
      <Routes>
        <Route path="/search" element={<Search />} />  // "/A/search" or "/search/search"
        <Route path="/B/B1/show" element={<Show />} /> // "/A/B/B1/show" or "/search/B/B1/show"
      </Routes>
      <div>Footer</div>
    </div>
  );
}

Edit react-router-v6-how-to-set-a-route-with-absolute-path

Since Home is rendered on both "/A" and "/search" as a root route, it can link relative to "search" and "B/B1/show" from either root path.

Sandbox code to demo this behavior:

function Home() {
  return (
    <div>
      <div>Home</div>
      <NavLink to="search">Search</NavLink>{" "}
      <NavLink to="B/B1/show">Show</NavLink>
      <Routes>
        <Route path="/search" element={<Search />} />
        <Route path="/B/B1/show" element={<Show />} />
      </Routes>
      <div>Footer</div>
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <ul>
        <li>
          <NavLink to="/A">A</NavLink>
        </li>
        <li>
          <NavLink to="/search">Search</NavLink>
        </li>
      </ul>
      <Routes>
        <Route path="/A/*" element={<Home />} />
        <Route path="/search/*" element={<Home />} />
        <Route path="*" element={<Navigate to="/A" replace />} />
      </Routes>
    </div>
  );
}

While React Router claims that absolute file paths still work in V6 on their website:

Note: Absolute paths still work in v6 to help make upgrading easier. You can even ignore relative paths altogether and keep using absolute paths forever if you'd like. We won't mind.

I'm not convinced it actually does for a subset of users who want this.

You can see the merge request for this functionality here but it explicitely calls out that this will only work if the child routes have the same path as the parent routes.

Child routes with absolute paths that do not match their parent routes are an error.

Unfortunately for many of us, our child routes in websites using React Router pre-v6 don't have the same paths as their parent routes.

One possible solution is listed in this thread by user @jampy where they propose replacing the Routes component with a custom component that ignores the parent's path, thus allowing its Route components to use absolute paths.

Related