skip to Main Content

In the React project, I am creating the admin dashboard and the UI area that users will see.

I couldn’t separate the admin theme from the PublicTheme.

When I go to /admin/login as the URL, I still see the publicheader and publicfooter in the PublicThemewhile I should see adminheader and adminfooter.

I’m using react-router-dom v6.

AdminTheme

import Header from "../compenents/layout/Admin/Header";
import Footer from "../compenents/layout/Admin/Footer";

const AdminTheme = ({ children }) => {
  return (
    <>
      <Header />
      {children}
      <Footer />
    </>
  );
};
export default AdminTheme;

PublicTheme

import Header from "../compenents/layout/Public/Header";
import Footer from "../compenents/layout/Public/Footer";

const PublicTheme = ({ children }) => {
  return (
    <>
      <Header />
      {children}
      <Footer />
    </>
  );
};
export default PublicTheme;

AdminRoute

export default function AdminRoute() {

  return (
    <Routes>
      <Route path="admin/login" element={<Login />} />
      <Route path="admin/posts" element={<Post />} />
    </Routes>
  );
}

PublicRoute

export default function PublicRoute() {
  return (
    
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/projects" element={<Project />} />
      <Route path="/blog" element={<Blog />} />
      <Route path="/posts" element={<Post />} />
      <Route path="*" element={<Page404 />} />
    </Routes>
  );
}

App.js

function App() {
  return (
    <>
      <PublicTheme>
        <main className="container mx-auto px-2 sm:px-4 pt-12">
          <div className="flex flex-col lg:flex-row justify-between gap-x-8 mb-20">
            <PublicRoute />
          </div>
        </main>
      </PublicTheme>

      <AdminTheme>
        <AdminRoute />
      </AdminTheme>
    </>
  );
}
export default App;

2

Answers


  1. The PublicTheme and the AdminTheme are being rendered in the root of the app component. Add some conditions render based on the route.

    I would create a LayoutRouter where you will handle the condition based on the route:

    import { Outlet, useLocation } from 'react-router-dom';
    
    function LayoutRouter() {
      const location = useLocation();
    
      if (location.pathname.startsWith('/admin')) {
        return <AdminTheme><Outlet /></AdminTheme>;
      }
      return <PublicTheme><Outlet /></PublicTheme>;
    }
    

    And then in the app.js update it:

    import { BrowserRouter, Routes, Route } from 'react-router-dom';
    
    function App() {
      return (
        <BrowserRouter>
          <Routes>
            <Route path="/" element={<LayoutRouter />}>
              <Route index element={<Home />} />
              <Route path="/projects" element={<Project />} />
              <Route path="/blog" element={<Blog />} />
              <Route path="/posts" element={<Post />} />
              <Route path="admin/login" element={<Login />} />
              <Route path="admin/posts" element={<Post />} />
              <Route path="*" element={<Page404 />} />
            </Route>
          </Routes>
        </BrowserRouter>
      );
    }
    
    export default App;
    
    Login or Signup to reply.
  2. One way is to use conditional rendering :

    App.js

    function App() {
    
      const location = useLocation() 
    
      return !location.pathname.includes('/admin') ? (        
          <PublicTheme>
            <main className="container mx-auto px-2 sm:px-4 pt-12">
              <div className="flex flex-col lg:flex-row justify-between gap-x-8 mb-20">
                <PublicRoute />
              </div>
            </main>
          </PublicTheme>
       ) : (
          <AdminTheme>
            <AdminRoute />
          </AdminTheme>
       )        
      );
    
    }
    export default App;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search