Nested dynamic routes with createBrowserRouter

I’m currently working on a forum-type project for fun and experience, using Router to handle loading boards and threads from MongoDB. I’ve enocuntered a problem- board URLs work, but trying to nest a thread URL within that (i.e. get thread number XX in board YY):

  { path: "/board/:id", element: <BoardPage />,
     children: [{ path:"/board/:id/:tid", element: <ThreadPage /> }],

Just returns the board page.
Now the thing is I have actually solved this, but it’s somewhat… silly.

  { path: "/board/:id", element: <BoardOrThread />,
     children: [{ path:"/board/:id/:tid", element: <BoardOrThread /> }],
function BoardOrThread(props) {

const params = useParams();

//if ('tid' in params)
if (params.hasOwnProperty('tid')) {
return(
<ThreadPage params={params} />
);
}
//else...
return(
<BoardPage params={params} />
);
}

Basically, the BoardOrThread component checks if the tid (thread ID) value exists in params, if it does it returns an instance of the ThreadPage component, else it returns a BoardBage. This works, but almost certainly not how this is supposed to be done. Is what I’m trying to do possible, and if so, how do I do it properly?

Hi, @krcdavis!

Exciting times ahead. I may be biased, but I love forum-type projects :smiley:

I actually asked v0 for some pointers on this, and it got back to me with some suggestions:

  1. Layout Route Pattern: Create a parent layout component that handles the board context and uses React Router’s Outlet to render either the board or thread component based on the current route.
  2. Proper Path Nesting: Define separate routes with a clear hierarchical structure (/board/:id and /board/:id/thread/:tid) that maintains the parent-child relationship in the URL.
  3. Conditional Rendering with useMatch: Use the useMatch hook to determine which component to render based on the current URL pattern, allowing a single component to handle both board and thread views.
  4. Loader Functions: Leverage React Router’s data loading capabilities to fetch the appropriate data for each route, separating data fetching logic from rendering components.

I hope that helps!

Hey, thanks! It currently is and will probably remain unusably simple, but I’m having fun and learning things.
Those suggestions feel kind of vague, but I’ll look into them. useMatch sounds like about what I’m doing but actually properly implemented.

1 Like

Feel free to go directly into v0.dev and maybe import more of your code, it’ll help get more personalised suggestions.

1 Like