Home > Blockchain >  React Router, hide Nav & footer on certain pages. with Router V6
React Router, hide Nav & footer on certain pages. with Router V6

Time:03-12

So i have tried for quiet some time to hide the nav and footer components in certain pages of the site, but sadly no luck. I've tried multiple solutions on Stackoverflow, only one of them worked partially by creating a new Layout component and then putting that inside the Routes to then exclude the footer and nav from for example the login page. But the issue was that it worked, but on homepage it then only showed the footer and nav, and nothing in between like the design I made in the homepage.

The only solution that works for me is by creating the and like I did in the example, but then I cant exclude certain pages and hide them there...

This is how it looks currently and not working:

import React from "react";
import Home from ".//Pages/Home";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Dashboard from "./Pages/Dashboard";
import Login from "./Pages/Login";
import Price from "./Pages/Price";
import ErrorPage from "./Pages/ErrorPage";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
import Profile from "./Pages/Profile";

function App() {
  return (
    <Router>
      <nav>
        <Navbar />
      </nav>

      <Routes>
        <Route index element={<Home />} />
        <Route path="/Dashboard" element={<Dashboard />} />
        <Route path="/Login" element={<Login />} />
        <Route path="/Price" element={<Price />} />
        <Route path="/Profile/:username" element={<Profile />} />

        <Route path="/*" element={<ErrorPage />} />
      </Routes>

      <footer>
        <Footer />
      </footer>
    </Router>
  );
}

export default App;

CodePudding user response:

Hi you can do it by having a state that only when the state is true the nav and footer will render:

function App() {

  const [showNav, setShowNav- = useState(true);

  return (
    <Router>
   {   showNav &&
          <nav>
            <Navbar />
          </nav>
   } 
      <Routes>
        <Route index element={<Home />} />
        <Route path="/Dashboard" element={<Dashboard />} />
        <Route path="/Login" element={<Login />} />
        <Route path="/Price" element={<Price />} />
        <Route path="/Profile/:username" element={<Profile />} />

        <Route path="/*" element={<ErrorPage />} />
      </Routes>

    {showNav &&
          <footer>
            <Footer />
          </footer>
        </Router>

    }
  );
}

And for example, if you don't want to show the nav in the homepage you will pass the setShowNav function as a prop and will set it to false:

<Route index element={<Home funcNav={setShowNav}/>} />

in home page:

props.funcNav(false);

CodePudding user response:

You can also use UseLocation from react-router-dom

const { pathname } = useLocation();
      <footer>
         {pathname !== '/<SOME_ROUTE>' &&
        <Footer />}
      </footer>

CodePudding user response:

You can use modularization in your app segmenting it into different sections. This can best be accomplished by using nested routes in your app each. For example you could have example.com/routes/xxx have one layout and have example.com/other/xxx have another layout... You could also use this to optionally render the navbar and footer as you have mentioned.

It is a good idea to segment your app if it has very different features/areas where different navbar/footer combinations need to be used. Here is an example using most of your code which would segment it into a main layout, and no layout.

App.js

import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import PageWithoutHeaderOrFooter from "./Pages/NoHeaderOrFooter";
import MainLayoutRoutes from "./Layouts/MainLayoutRoutes";

function App() {
    return (
        <Router>
            <Routes>
                <Route path="/noheaderorfooter" element={<PageWithoutHeaderOrFooter />} />
                <Route path="*" element={<MainLayoutRoutes />} />
            </Routes>
        </Router>
    );
}

export default App;

MainLayuotRoutes.js

import React from 'react';
import Home from ".//Pages/Home";
import Dashboard from "./Pages/Dashboard";
import Login from "./Pages/Login";
import Price from "./Pages/Price";
import ErrorPage from "./Pages/ErrorPage";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
import Profile from "./Pages/Profile";
function MainLayoutRoutes() {
    return (
        <React.Fragment />
            <nav>
                <Navbar />
            </nav>{/*This is outside the routes component on purpose read below*/}
            <Routes>
                <Route index element={<Home />} />
                <Route path="/Dashboard" element={<Dashboard />} />
                <Route path="/Login" element={<Login />} />
                <Route path="/Price" element={<Price />} />
                <Route path="/Profile/:username" element={<Profile />} />
                <Route path="/*" element={<ErrorPage />} />
            </Routes>
            <footer>
                <Footer />
            </footer>
        <React.Fragment />
    )
}

export default MainLayoutRoutes;

A couple things I would like to note about this code.
First each child component in a Routes component must be a Route component (this doesn't include the element part of the Route component). This is why I am using a React.Fragment (you could have just as easily used <></>) if you didn't want an additional div rendered.
Secondly using this type of routing is good for segmenting your app into areas... Using areas not only is better for routing it is also better for SEO (where applicable as some crawlers don't yet support JavaScript).
Lastly I would like to mention if there is a rare case where there is only 1 page that you want a different navbar or footer, just use conditional rendering to take care of the edge case.

CodePudding user response:

yes you should apply condition that will check if current location will display nav or not You should use useLocation from react-router To do this

  • Related