2

I did not know how to construct the proper question title, sorry for that. But in a route structure like below, I want the admin path to always show organisations as the default/index, like whenever you navigate to /admin it automatically navigates to /admin/organisations, but for instance in other path /admin/users, or /admin/organisations/create the related components renders.

is such a requirement doable with routes, createBrowserRoute?

const routes = createBrowserRouter([
  {
    path: '/',
    element: <AppShell />,
    children: [
      {
        path: 'admin',
        element: <AdminPanel />,
        children: [
          { path: 'organisations', element: <Organisations /> },
          { path: 'users', element: <Users /> }
        ]
      }
    ]
  }
]);

currently, I have a useEffect in the AdminPanel component like

React.useEffect(()=>{
    if(window.location.pathName === "/admin" ) navigate("/admin/organisations")
},[])

But is it doable via react-router props?

I have chosen this structure (children array) because all the sub-admin paths should have access to the side menu and according to react-router official tutorial it was the best approach

OBS! index element takes the route/path name of the parent, in my case I wanted the index behavior with a different path name. So it is not considered a duplicate of the flagged question, at least the accepted answer there does not answer my question, though the second answer does.

Amir-Mousavi
  • 4,273
  • 12
  • 70
  • 123

3 Answers3

3

also you can use this : Link

const router = createBrowserRouter([
  {
    path: '/',
    element: <AppShell />,
    children: [
      {
        path: 'admin',
        element: <AdminPanel />,
        children: [
          {
            index: true,
            element: <Navigate to="/admin/organisations" replace />,
            // when user navigate to /admin it automaticly navigate to /admin/organisations
          },
          { path: 'organisations', element: <Organisations /> },
          { path: 'users', element: <Users /> },
        ],
      },
    ],
  },
]);
Abbas Bagheri
  • 790
  • 5
  • 10
  • 1
    As I am using a common layout for all children which are rendered as `Outlet` , this answer is the best choice for me – Amir-Mousavi Feb 21 '23 at 14:00
0

Your AdminPanel may be like this:

import React from 'react'
import {
  Navigate,
  Outlet,
  useLocation,
} from 'react-router-dom'

const AdminPanel = () => {
  const { pathname } = useLocation()
  //... you code ...//

  return (
    pathname === '/admin' ? <Navigate to="/admin/organisations" replace /> : <Outlet />
  )
}
Pavel Sturov
  • 315
  • 7
0

You can create a catch all route and put it at the bottom of the array.

const routes = createBrowserRouter([
  {
    path: '/',
    element: <AppShell />,
    children: [
      {
        path: 'admin',
        children: [
          { path: 'users', element: <Users /> }
          { path: '*', element: <Organisations /> },
        ]
      }
    ]
  }
]);

You have 3 options that might help you: splats (link), basename (link) and layout routes(link).

It seams that /admin is a layout route that specifies that users might see some sort of dashboard that renders only its contents (common usecase: display a sidebar visible only for the admins).

Netherless, you can also use the <Navigate> (link) element to move from one component to another:

const routes = createBrowserRouter([
  {
    path: '/',
    element: <AppShell />,
    children: [
      {
        path: 'admin',
        element: <Navigate to="/admin/organisations" replace/>,
        children: [
          { path: 'users', element: <Users /> }
          { path: 'organisations', element: <Organisations /> },
        ]
      }
    ]
  }
]);
dav1app
  • 819
  • 8
  • 7