Rafael
Rafael

Reputation: 2731

Is there a way to set a default route with React-Router v6

I just can't find a way to set a default route with react-router v6

Is it because it's not a recommended programming approach anymore?

Upvotes: 77

Views: 74536

Answers (9)

Drew Reese
Drew Reese

Reputation: 202751

If I understand your question about a "default" route correctly then I am interpreting this as one of the following:

  1. Use an index route:

    You can wrap a set of routes in a layout route and specify an index route:

    <Routes>
      <Route path="/">
        <Route index element={<ComponentA />} />
        <Route path="pathA" element={<ComponentA />} />
        <Route path="pathB" element={<ComponentB />} />
        <Route path="pathC" element={<ComponentC />} />
      </Route>
    </Routes>
    

    or

    <Routes>
      <Route path="/">
        <Route index element={<Navigate to="pathA" replace />} />
        <Route path="pathA" element={<ComponentA />} />
        <Route path="pathB" element={<ComponentB />} />
        <Route path="pathC" element={<ComponentC />} />
      </Route>
    </Routes>
    

    The index route is the route that will be matched and rendered when the path exactly matches the root parent route's path.

  2. Redirect to a "default" route if no other routes match:

    You can also render a redirect to the route you consider to be the "default" route.

    <Routes>
      <Route path="/pathA" element={<ComponentA />} />
      <Route path="/pathB" element={<ComponentB />} />
      <Route path="/pathC" element={<ComponentC />} />
      <Route path="*" element={<Navigate to="pathA" replace />} />
    </Routes>
    

Upvotes: 121

akwasiijunior
akwasiijunior

Reputation: 175

If you want the user to navigate to start component from / then use this.

Ex: website is www.mywebsite.com and you want your users to be directed to the start pages component.

// main.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";
..other imports..

const router = createBrowserRouter([
  {
    path: "react-bootstrap/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "home",
        element: <Home />,
      },
      {
        path: "", // this right here
        element: <Home />,
      },
      {
        path: "about",
        element: <About />,
      },
      {
        path: "contacts",
        element: <Contact />,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
)

Reason for this is because Im rendering the component inside with a fixed <Header/> and </Footer> components.

Upvotes: 1

Rafat Khandaker
Rafat Khandaker

Reputation: 1

You can use this code snippet below: the default child element path set to emptyString "" becomes the default route.

 import { createBrowserRouter,RouterProvider } from "react-router-dom";
    
    class App extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                yourObject: null
            };
        }
        router = createBrowserRouter([
            {path: "/", children: [ 
                {path:"", element: <Default/>},
                {path:"pathA", element: <ComponentA/>},
                {path:"pathB",  element: <ComponentB/> },
                {path:"pathC",  element: <ComponentC /> }
           ]}]);
        render() { return ( <RouterProvider router={this.router} /> ) }
    }

Upvotes: 0

Here is my working solution using "createBrowserRouter":

    const router = createBrowserRouter([
        {
          path: "/",
          element: (
            <Root />
          ),
          children: [
            {
              path: "/",
              element: <Navigate to={"/" + pageIds.home} replace={true} />,
                }, 
            {
              path: pageIds.home,
              element: (<Homepage />),
            },
          ]
        },
    ]);

The reason I use the "Navigate" component is so that I'm not duplicating my use of the "Homepage" component, which has a lot of parameters (not shown here).

Upvotes: 2

Joseph Markle
Joseph Markle

Reputation: 1

You can make the path a variable like this:

      <Route path=':default' Component={LandingPage2}></Route>

Upvotes: 0

Vignesh K
Vignesh K

Reputation: 279

If you are using createBrowserRouter you can set the default route in following way.


const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      { index: true, element: <Navigate to="/calculation" replace /> },
      { path: "calculation", element: <Calculation /> },
      { path: "calendar", element: <Calendar /> },
      { path: "profile", element: <Profile /> },
    ],
  },
]);

Upvotes: 27

vaibhavmaster
vaibhavmaster

Reputation: 687

If you are using createBrowserRouter you can set the default route in following way.

As per docs component loads children of parent. So

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    children: [
      {
        path: "/",
        element: <Home />,
      },
      {
        path: "/home",
        element: <Home />,
      },
    ],
  },
],);

Upvotes: 3

Oussama Boumaad
Oussama Boumaad

Reputation: 632

TLDR;

use <Route index element={<Navigate to="/dashboard" />} />

index: default computed route.

<Navigate to="whatever you want"/>: is used to navigate to a another already declared path.

LR;

I found an easy way to redirect to a default component using index & Navigate combined.

In my situation I had used React Router V6.6.2 with:

createBrowserRouter(
    createRoutesFromElements(...))

The routes look like this

/* All imports go here */ 

const router = createBrowserRouter(
    createRoutesFromElements(
        <Route element={<AuthLayout />}>
            <Route element={<RrotectedLayout />}>
                <Route path="/" element={<MainLayout />}>
                    <Route index element={<Navigate to="/dashboard" />} />
                    <Route path="dashboard" element={<Dashboard />} />
                    <Route path="projects" element={<Projects />} />
                    <Route path="users" element={<Users />} />
                    <Route path="notifications" element={<Notification />} />
                    <Route path="settings" element={<Settings />} />
                    <Route
                        path="*"
                        element={<Navigate to="/dashboard" replace={true} />}
                    />
                </Route>
            </Route>
            <Route path="/signup" element={<Signup />} />
            <Route path="/login" element={<Login />} />
        </Route>,
    ),
    {},
)

export default function App() {
    return (
        <>
            <RouterProvider router={router} />
        </>
    )
}

Now when you access your application, React router will figure out which index your application needs to point to, and since your index contains a Navigation to a specific path, you'll be redirect to that path by default. you don't need to specify a specific component (element) in this situation because you don't wanna loose the link to it.

Upvotes: 20

Lucas Nantes
Lucas Nantes

Reputation: 30

I actually found the answer here but I just wanna share my solution if it helps someone with theirs.

You can set path='*' to make a default route. The index route deals a parent route ("/") but doesn't deal with routes which should otherwise return a 404 status.

if (!token) {
    // This router will handle my public routes. Anything else is going to redirect to AuthPage without losing the previous route typed.
    return (
      <BrowserRouter>
        <Routes>
          {/* Auth  */}
          <Route path="/">
            <Route exact path="recover" element={<UnknownPage />} />
            // Default route
            <Route path="*" element={<AuthPage setToken={setToken} />} />
          </Route>
        </Routes>
      </BrowserRouter>
    );
  }

  // This router is inside my application. Only logged users will get here.
  return (
    <BrowserRouter>
      <Routes>
        {/* My base page is just some fixed structure like Header, Sidebar and Footer. For this problem you can ignore it. */}
        {/* BasePage  */}
        <Route path="/*" element={<BasePage logout={logout} />}>
          {/* This is my specific users route */ }
          {/* Users */}
          <Route path="users">
            <Route path="" element={<UsersPage />} />
            <Route path=":id" element={<UserInfoPage />} />
          </Route>

          {/* Anything else is going to show this page. Even random words like:  http:localhost:3000/anything-asdvasd */}
          {/* Default Route */}
          <Route path="*" element={<UnknownPage />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );

Using parent routes like I used in my users routes makes it easier to scope your default routes.

Upvotes: 0

Related Questions