Accepted answer

I think you are complicating the route protection a bit. react-router-dom@6 route rendering works quite differently in v6, we don't directly render a Route in our components, they are to be rendered into the Routes component or directly nested under other Route components for route nesting.

I suggest the following implementation:

import React from "react";
import { Navigate, Outlet } from "react-router-dom";

interface IConditionalRoute = {
  condition: boolean;

const ConditionalRoute = ({ condition = false }: IConditionalRoute) => {
  return condition ? <Outlet /> : <Navigate to={REDIRECT_DESTINATION} />;

export { ConditionalRoute };

Note: I'm not super strong in Typescript, so I might not have got the syntax completely correct, but I expect the interface/code should get you close to what you would need.


The AdminRoute would be rendered on what is called a layout route, a route that renders an Outlet and wraps other Route components. Omit the path prop so the path of the nested routes is what is used for matching/rendering.

const AdminRoute: ConditionalRouteProps = () => {
  const { isAdmin } = useContext(UserContext);
  return <ConditionalRoute condition={isAdmin} />;

const TestRoutes: React.FC = () => {
  return (
      <Route element={<AdminRoute />}>
        <Route path="/admin" element={<h1>Admin Page</h1>} />
      <Route path="/" element={<TestPage />} />

Related Query

More Query from same tag