Nick
Nick

Reputation: 1541

React Router v6 Redirects

thank you for taking the time to review this question in advance. I have experience with v5 but since changed pretty significantly in v6 I'm quite confused on how to setup a redirect within a nested page.

For example my page structure is as follows:

- /auth
- /client
  - dashboard
  - settings
    - profile
    - password

In my /client route i have a redirect set as follows (where APP_URL = /client:

<Route path="/*" element={<Navigate to={`${APP_URL}/dashboard`} />} />

However, within my /settings route i would like to have it so that /settings redirects to /settings/profile. When setting a redirect within a nested route that also has a redirect it appears to cause an endless loop or redirect to the redirect set within the parent.

App.tsx

function App() {
  return (
    <div className="App">
      <Router>
        <Routes>
          <Route path="*" element={<Views />}/>
        </Routes>
      </Router>
    </div>
  );
}

Views

export const Views = () => {
    return (
        <Routes>
            <Route path="*" element={<Navigate to={APP_URL} />} />
            <Route path={`${APP_URL}/*`} element={<AppLayout />} />
        </Routes>
    )
}

AppLayout

export const AppLayout = () => {
    return (
        <Content>
            <AppViews />
        </Content>
    )
}

AppViews

export const AppViews = () => {
    return (
        <Routes>
            <Route
                path="/*"
                element={<Navigate to={`${APP_URL}/dashboard`} />}
            />
            <Route path={`/dashboard`} element={<Dashboard />} />
            <Route path={`/settings/*`} element={<Settings />} />
        </Routes>
    )
}

Settings

const Settings = () => {
    return (
        <>
            <Routes>
                <Route
                    path="/*"
                    element={<Navigate to={`${APP_URL}/settings/profile`} />}
                />
                <Route path={`/profile`} element={<Profile />} />
                <Route path={`/password`} element={<Password />} />
            </Routes>
        </>
    )
}

Does anyone have any experience with this?

Upvotes: 1

Views: 1349

Answers (2)

Drew Reese
Drew Reese

Reputation: 203408

You are mixing up absolute paths for relative paths. Since you are rendering Settings on a "/settings" path all the nested routes need to also be rendered as subroutes.

const Settings = () => {
  return (
    <>
      <Routes>
        <Route
          path="/*"  // "/"
          element={<Navigate to={`${APP_URL}/settings/profile`} />}
        />
        <Route path={`/profile`} element={<Profile />} />   // "/profile"
        <Route path={`/password`} element={<Password />} /> // "/password"
      </Routes>
    </>
  )
}

Given:

<Route path="/settings/*" element={<Settings />} />

Using relative paths:

const Settings = () => {
  return (
    <>
      <Routes>
        <Route path="profile" element={<Profile />} />   // "/settings/profile"
        <Route path="password" element={<Password />} /> // "/settings/password"
        <Route
          path="*"
          element={<Navigate to="../profile" />}         // "/settings/profile"
        />
      </Routes>
    </>
  )
}

Using absolute paths:

const Settings = () => {
  return (
    <>
      <Routes>
        <Route path={`/${APP_URL}/profile`} element={<Profile />} />   // "/settings/profile"
        <Route path={`/${APP_URL}/password`} element={<Password />} /> // "/settings/password"
        <Route
          path={`/${APP_URL}`}
          element={<Navigate to={`/${APP_URL}/profile`} />}  // "/settings/profile"
        />
      </Routes>
    </>
  )
}

Upvotes: 1

Nikko Khresna
Nikko Khresna

Reputation: 1009

I believe route with asterisk should be put at the bottom to be fallback for routes that are not listed, lemme know this doesnt fix your issue

<Routes>
                <Route path={`/profile`} element={<Profile />} />
                <Route path={`/password`} element={<Password />} />
                <Route
                    path="/*"
                    element={<Navigate to={`${APP_URL}/settings/profile`} />}
                />
            </Routes>

Upvotes: 0

Related Questions