1

I'm working on a Twitter clone using the MERN stack, and couldn't wrap my head around routes, let me explain a bit more, I want the design of the login page to be separated from the entire app, so I'm using styled-components and wrapped the login page, other pages and both sidebars with the theme provider as shown below.

return (
<ThemeProvider theme={theme}>
  <Provider store={store}>
    <GlobalStyles />
    <MainStyle>
      <Router>
        {window.location.pathname !== "/" && <LeftPanel />}
        <Routes>
          <Route path="/" element={<LoginPage />} />
          <Route path="/home" element={<Home />} />
          <Route path="/user" element={<User />} />
        </Routes>
      </Router>
      {window.location.pathname !== "/" && <RightPanel />}
    </MainStyle>
    {window.location.pathname !== "/" && <MobileBar />}
  </Provider>
</ThemeProvider>

You might be wondering why I added window.location.pathname well, I needed to check if this is the login page so I don't include the sidebars because I only want the sidebars to be shown when it's NOT the login page, That worked fine for a while until I started the authentication process and BOOM my trick didn't work as expected, the two sidebars won't show up and some other CSS didn't work properly either, so I decided to change the structure to this instead...

return (
<ThemeProvider theme={theme}>
  <GlobalStyles />
  <Router>
    <Routes>
      <Route path="/" element={<LoginPage />} />
      <Route path="/app/*" element={<RestOfApp />} />
    </Routes>
  </Router>
</ThemeProvider>

What I did above was I made a nested route so I can group all the pages away from the login page and style them the way I want, here's how the RestOfApp component looks...

<>
  <MainStyle>
    <LeftPanel />
    <Routes>
      <Route path="/home" element={<Home />} />
      <Route path="/user" element={<User />} />
    </Routes>
    <RightPanel />
  </MainStyle>
  <MobileBar />
</>

Now the home route became /app/home instead of just /home which upsets me :( but hey at least it worked, but unfortunately wasn't the perfect solution.

I know looks stupid :D but that was the best thing I could think of, luckily that fixed my issue but I feel there's a better way, however, that solution wasn't perfect I keep getting errors in the chrome inspect element like the image is not found.

background.png:1          GET http://localhost:3000/app/background.png 404 (Not Found)

which is the background image on the login page :(

Is there any better way to structure my app?!

Thanks in advance.

Mark Skelton
  • 3,663
  • 4
  • 27
  • 47

1 Answers1

1

React Router has the concept of "layout routes" which allow you to wrap a set of routes in a common layout without impacting the structure of the URL. For your app, this might look something like this:

<Routes>
  <Route path="/" element={<LoginPage />} />
  <Route element={<AppLayout />}>
    <Route path="/home" element={<Home />} />
    <Route path="/user" element={<User />} />
  </Route>
</Routes>

Then, inside of your AppLayout component you can render an <Outlet> component which will be replaced with the nested route (e.g. home or user).

import { Outlet } from 'react-router-dom'

function AppLayout() {
  return (
    <>
     <MainStyle>
       <LeftPanel />
       <Outlet />
       <RightPanel />
     </MainStyle>
     <MobileBar />
    </>
  )
}

Check out the React Router docs for more details about layout routes.

Mark Skelton
  • 3,663
  • 4
  • 27
  • 47