1

I want my React website normally to have an "app shell" (header, footer, sidebar with menu, etcetera) but for specific URI paths...I want those "app shell" elements to disappear. I am new to React and React Router, so I came up with this (incorrect) solution:

import { OuterShell } from './OuterShell';
import Home from './home';
import About from './about';
import Login from './login';
import { Route, Routes } from "react-router-dom";

function App() {
  return (
    <>
      <MantineProvider withGlobalStyles withNormalizeCSS theme={{
        fontFamily: "fantasy",
        colorScheme: "dark"
      }}>
        <div className="App">
          <Routes>
            //This "OuterShell" contains my Mantine "App Shell" (header, footer, menu...).
            <OuterShell>
              <Route path="/" element={<Home />} />
              <Route path="/about" element={<About />} />
            </OuterShell>

            //HERE IS THE ISSUE...
            //I want this component path to render WITHOUT the "App Shell" 
            <Route path="/login" element={<Login />} />
          </Routes>
        </div>
      </MantineProvider>
    </>
  )
}

As soon as I remove the <Route path "/login" /> element, then my app starts working again. So I conclude this is an incorrect way to use React Router.

What then is the proper way to achieve the result I'm looking for? That is, I want the Login component to be rendered full-screen, without the "app shell".

Incidentally the React Router <BrowserRouter/> element is indeed present, and is rendered outside my <App /> element. Thus my SPA is working correctly, as long as I remove that aforementioned Login route. Also, my website is built with Vite - in case that is relevant.

UPDATE

I re-studied the react-router-dom documentation, and discovered what looks like the perfect solution for my need. UNFORTUNATELY, the code feature I want doesn't work as documented. I have simplified my original code into exactly what I need, which is this:

<Routes>
  <Route path="/" element={<button />}>
    <Route index element={<div>WARP</div>} />
    <Route path="drive" element={<div>DRIVE</div>} />
  </Route>
  <Route path="success" element={<div>SUCCESS</div>} />
</Routes>

According to the documentation, the above should be able to give me a button labeled with either "WARP" or "DRIVE" depending on the route. Instead, the button for those routes is rendered with no text at all!

I can force a partial result I'm looking for, minus the "success" path, with the following code:

<button>
  <Routes>
    <Route path="/" element={<div>WARP</div>} />
    <Route path="about" element={<div>DRIVE</div>} />
  </Routes>
</button>

The above code works, but for only two of the three routes I want. Again, my ideal example is supposed to work - it comes directly from the documentation but doesn't work!

Any ideas?

My dependencies:

    "react-dom": "^18.2.0",
    "react-router-dom": "^6.6.1",
Brent Arias
  • 29,277
  • 40
  • 133
  • 234
  • Just a thought, it seems like you might be over thinking it. Just use simple conditional rendering - if user is not logged in, show `` otherwise, show your router configuration. Why would this not work for you? – Randy Casburn Dec 26 '22 at 18:29
  • @RandyCasburn Maybe that could be my answer. Ultimately I'm engaged in a learning process. One of the anticipated goals I have is to create several (a dozen or more?) landing pages that are free from the "app shell". At face value, if I need to conditionally render components based on URI route...it kinda makes me wonder what value React Router actually provides. Again, I'm new to this. – Brent Arias Dec 26 '22 at 18:39
  • There is no router, in any framework, that is designed to make decisions about _what is in the view_ - they only decide which view/controller to activate given a requested route. – Randy Casburn Dec 26 '22 at 18:42
  • Not overthinking anything at all. RRDv6 has what are called [Layout Routes](https://reactrouter.com/en/main/start/concepts#layout-routes) for this purpose. – Drew Reese Dec 28 '22 at 22:34
  • Does it make sense perhaps to have two `App.tsx` root components for my needs? One that handles everything wrapped in the App Shell, and the other for one-off pages that omit the wrapping? – Brent Arias Dec 29 '22 at 22:43

0 Answers0