I am building a website and I don't want to display the navbar in 2 pages. One is the 404 page where I will be giving a redirect button. The other is the landing page of the website where I will be a giving a button which would redirect to the home page of the website. This is my app.js code where I have my routes defined.
import React from "react";
import "./App.css";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Navbar from "./Components/Navbar";
import Home from "./Components/Pages/Home";
import PlanYourTrip from "./Components/Pages/PlanYourTrip";
import AboutUs from "./Components/Pages/AboutUs";
import SafetyMeasures from "./Components/Pages/SafetyMeasures";
import Travel from "./Components/Pages/Travel";
import Error from "./Components/Pages/404";
function App() {
return (
<>
<Router>
<Navbar />
<Switch>
<Route path="/" exact component={Travel} />
<Route path="/home" exact component={Home} />
<Route path="/plan-your-trip" exact component={PlanYourTrip} />
<Route path="/about-us" exact component={AboutUs} />
<Route path="/safety-measures" exact component={SafetyMeasures} />
<Route component={Error} />
</Switch>
</Router>
</>
);
}
export default App;
I want to remove the navbar from <Route path="/" exact component={Travel} /> and <Route component={Error} /> . Please help.
<Navbar /> needs to check to window.location and render empty
See https://reactrouter.com/web/api/Hooks/uselocation
Or create a new component that does the check and render it children
<MayRenderNav><Navbar /></MayRenderNav>
The problem with your code is that <Navbar /> component will load without caring about the route.
You can simply put your <Navbar /> component inside the components you want it to load in and simply leave for others.
To add more context on uke answer you can use the useLocation hook inside your navbar an do something like this
// All the routes you want to exclude
const withouSidebarRoutes = ["/about"];
function Navbar() {
const {pathname} = useLocation();
// Validates if the current pathname includes one the routes you want to hide the sidebar is present on the current url
// If that's true render null instead of the sidebar
if (withouSidebarRoutes.some((item) => pathname.includes(item))) return null;
return (
//your navbar code.
)
}
The includes is useful because if you have nested routes like about/1 it will exclude that one too, use a simple equal if you just want to exclude the about page and not the nested ones.
withouSidebarRoutes.some((item) => pathname === item)
Check the hooks api reference to see what the useLocation can do: https://reactrouter.com/web/api/Hooks/uselocation
Also I have a working sandbox with a sidebar that hides when you're in the about section.
https://codesandbox.io/s/cranky-lewin-p8ozv
This might feel a bit cheat, but it does the trick.
To hide navbar from homepage (path = "/") is quite straight-forward. We can do by the book, use render in "Route".
The tricky part is how to hide from 404 Error page, which doesn't match all other route in your website.
The trick I used is to call useEffect on Error page mount, change style of navbar to display: none;
import React from "react";
import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import "./styles.css";
const NavBar = () => {
return (
<div className="navbar">
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
<Link to="/error">Error</Link>
</div>
);
};
const Home = () => (
<div>
<h1>This is home</h1>
<ul>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</div>
);
const About = () => <div>About</div>;
const Contact = () => <div>Contact</div>;
const Error = () => {
React.useEffect(() => {
document.getElementsByClassName("navbar")[0].style.display = "none";
}, []);
return (
<div>
<h1>Error</h1>
<Link to="/">Back to home</Link>
</div>
);
};
export default function App() {
return (
<Router>
<Route
render={({ location }) => {
if (location.pathname !== "/") return <NavBar />;
}}
/>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Route component={Error} />
</Switch>
</Router>
);
}
body {
margin: 0;
padding: 0;
}
.App {
font-family: sans-serif;
text-align: center;
}
.navbar {
background: black;
color: white;
padding: 10px 20px;
}
.navbar a {
display: inline-block;
padding: 6px 12px;
text-decoration: none;
color: white;
text-transform: uppercase;
}
Link to sandbox
Related
I'm trying to create my first website, but having issues with redirection to another page. I added Routes to App.jsx, and added links to Navbar; clicking on "Services" in Navbar goes to "/services", but the page doesn't show anything, only Navbar.
I also tried with NavLink, but it did't change anything. Please help me figure out what the problem is.
import React from 'react';
import "./App.css";
import { BrowserRouter, Routes,Route } from "react-router-dom";
import Home from './pages/home/Home';
import Samples from './pages/samples/Samples';
import Services from './pages/services/Services';
import Navbar from './components/navbar/Navbar';
import Reviews from './components/reviews/Reviews';
import Contacts from './components/contacts/Contacts';
const App = () => {
return (
<div>
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/services" element={<Services />} />
<Route path="/samples" element={<Samples />} />
{/* <Route path="#reviews" element={<Reviews />} /> */}
</Routes>
</BrowserRouter>
</div>
)
}
export default App
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { RiMenuFill, RiCloseLine } from 'react-icons/ri';
import './navbar.css';
import MainLogo from "../../assets/MainLogo.png";
const Navbar = () => {
const [toggleMenu, setToggleMenu] = useState(false);
return (
<div>
<div className='navbar'>
<Link style={{textDecoration:"none"}} to="/">
<img src={MainLogo} alt="main_logo" className="navbar_logo"/>
</Link>
<ul className='navbar_links'>
<li>
<Link to="/services">Services</Link>
</li>
<li>
<Link to="/samples">Samples</Link>
</li>
<li>
<Link to="/">Reviews</Link>
</li>
<li>
<Link to="#gallery">Gallery</Link>
</li>
<li>
<Link to="#about">About Us</Link>
</li>
<li>
<Link to="#contacts">Contacts</Link>
</li>
</ul>
</div>
There is no issue with the routing. The issue here is that the navbar uses fixed positioning and the "/services" route content is rendered under the navbar.
Give the App component some top margin to push the content down below the navbar.
Example:
const App = () => {
return (
<div className='app'> // <-- app container
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/services" element={<Services />} />
<Route path="/samples" element={<Samples />} />
{/* <Route path="#reviews" element={<Reviews />} /> */}
</Routes>
{/* <Reviews /> */}
</BrowserRouter>
</div>
)
}
app.css
.app {
margin-top: 93px; // <-- header/navbar height
}
I added {BrowserRouter} to index.js, and it worked
import React from "react";
import ReactDOM from "react-dom";
import App from './App';
import './index.css';
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
)
I have made landing page where onClick of button it redirects to the Menus page/component where I have declared Navbar component & here only I want to render the different news category component on click of multiple nav menus of Navbar.
By using react-router-dom V6 how can I render different categories of news component underneath of Navbar.
Below is the code which I have tried yet.
App.js
import React from 'react';
import {Routes,Route} from 'react-router-dom';
import LandingPage from './Components/LandingPage';
import Menus from './Component/Menus;
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<LandingPage/>} />
<Route path='menus' element={<Menus/>} />
</Routes>
</>
)
};
export default App;
Menus.js
import Navbar from './Navbar';
const Menus = () => {
return (
<div>
<Navbar/>
</div>
);
};
export default Menus;
Navbar.js
import '../Styles/Navbar.css';
import Entertainment from './Entertainment';
import Business from './Business';
import Health from './Health';
import Science from './Science';
import Sports from './Sports';
import Technology from './Technology';
import {Link,Route,Routes} from 'react-router-dom';
import {useState} from 'react';
const Navbar = ()=>{
const [isMobile,setIsMobile] = useState(false);
return(
<>
<nav className="navbar">
<h3 className="logo">theNews</h3>
<ul className={isMobile?'nav-links-mobile':'nav-links'}
onClick={()=>setIsMobile(false)}>
<Link to='/business' className='business'><li>Business</li></Link>
<Link to='/fun' className='fun'><li>Entertainment</li></Link>
<Link to='/health' className='health'><li>Health</li></Link>
<Link to='/science' className='science'><li>Science</li></Link>
<Link to='/sports' className='sports'><li>Sports</li></Link>
<Link to='/tech' className='tech'><li>Technology</li></Link>
</ul>
<button className='mobile-menu-icon' onClick={()=>setIsMobile(!isMobile)}>
{isMobile? <i className='fas fa-times'></i>:<i className='fas fa-bars' ></i>}
</button>
</nav>
<div>
<Routes>
<Route path='business' element={<Business/>}/>
<Route path='health' element={<Health/>} />
<Route path='science' element={<Science/>} />
<Route path='sports' element={<Sports/>} />
<Route path='tech' element={<Technology/>} />
<Route path='fun' element={<Entertainment/>} />
</Routes>
</div>
</>
)
}
export default Navbar;
If I understand your question correctly you are wanting to render Menus on the "/menus" path, and then also render sub-routes in Navbar being rendered by Menus. In react-router-dom v6 route paths are now always exactly matched, and the "/menus" root path precludes matching and rendering sub-routes.
The solution is to append a "*" wildcard matcher to the root path to allow additional route matching.
<Routes>
<Route path="/" element={<LandingPage/>} />
<Route path="/menus/*" element={<Menus/>} />
</Routes>
Additionally, in Navbar you are rendering relative route paths but specifying absolute route links. These should be in agreement. Remove the leading "/" character from the links so they are also relative to the "/menus" route path.
const Navbar = () => {
const [isMobile, setIsMobile] = useState(false);
return(
<>
<nav className="navbar">
<h3 className="logo">theNews</h3>
<ul className={isMobile?'nav-links-mobile':'nav-links'}
onClick={()=>setIsMobile(false)}>
<Link to='business' className='business'><li>Business</li></Link>
<Link to='fun' className='fun'><li>Entertainment</li></Link>
<Link to='health' className='health'><li>Health</li></Link>
<Link to='science' className='science'><li>Science</li></Link>
<Link to='sports' className='sports'><li>Sports</li></Link>
<Link to='tech' className='tech'><li>Technology</li></Link>
</ul>
<button className='mobile-menu-icon' onClick={()=>setIsMobile(!isMobile)}>
{isMobile? <i className='fas fa-times'></i>:<i className='fas fa-bars' ></i>}
</button>
</nav>
<div>
<Routes>
<Route path='business' element={<Business/>}/>
<Route path='health' element={<Health/>} />
<Route path='science' element={<Science/>} />
<Route path='sports' element={<Sports/>} />
<Route path='tech' element={<Technology/>} />
<Route path='fun' element={<Entertainment/>} />
</Routes>
</div>
</>
)
}
On the following Stackblitz:
https://stackblitz.com/edit/react-testing-routes-navigate-outside-kszb5l?file=src%2Fpages%2FPage2.jsx
I'm trying to include a:
BrowserRouter > Switch > Route > Component
inside another:
BrowserRouter > Switch > Route > Component.
Here is the code for: Page2.jsx:
import React from "react";
import { Link } from "react-router-dom";
import { BrowserRouter, Route, Switch } from "react-router-dom";
const Brush = ({color}) => {
return (
<div>
<div>Brush: {color}</div>
<div>
<Link to="/p2x">/p2x</Link><br />
<Link to="/p2y">/p2y</Link><br />
<Link to="/p2z">/p2z</Link><br />
</div>
</div>
);
};
class Page2 extends React.Component {
constructor(props) {
super(props);
this.state = {
letter: "B"
};
}
render() {
return (
<>
<div>You are currently on: Page 2 (Letter: {this.state.letter})</div>
<Link to="/">Page 1</Link><br />
<br />
<Link to="/page2/p2x">/page2/p2x</Link><br />
<Link to="/page2/p2y">/page2/p2y</Link><br />
<Link to="/page2/p2z">/page2/p2z</Link><br />
<br />
<Link to="/page3">Page 3</Link><br />
<BrowserRouter>
<Switch>
<Route path="/p2x" component={Brush} color="Red" />
<Route path="/p2y" component={Brush} color="Green" />
<Route path="/p2z" component={Brush} color="Blue" />
</Switch>
</BrowserRouter>
</>
);
}
}
export default Page2;
I would expect the brush component to be rendered somewhere on the red line.
Then, I would also expect to have also some other links there that allow me to internally browse between links:
{ /p2x, /p2y, /p2z }
Instead, I get nothing there.
Any idea on how to do that?
My goal is: Create some kind of widget with a few screens I can navigate from one to another. Then I was thinking of having a BrowserRouter in it. Later I could create a library with it that I could import into multiple projects. Do you think about any other way to do that?
Thanks!
In app.js file, you can define route in this way.
<Switch>
<Route exact path="/" component={Page1 } />
<Route path="/page2/p2x" component={Page2 } />
<Route path="/page2/p2y" component={Page2 } />
<Route path="/page2/p2z" component={Page2 } />
<Route path="/page3" component={Page3 } />
</Switch>
Then, in Page2 component, you can render Brush component with parameter from route.
I'm trying to properly render my different components with the HTML/CSS sidebar with React Routes and Apollo.
I have a sidebar that correctly renders to the left of the screen and a little navbar on top of it, the space for the component is not being blocked by any css property.
The expected output is:
The actual output:
I've tried to place all the Routes inside the sidebar but every time I click on them, they don't load at all, the URL changes but the content doesn't and I need to reload the webpage for it take some effect. The help would be very much appreciated.
App.js
import React from 'react';
import ApolloClient from 'apollo-boost';
import {ApolloProvider} from '#apollo/react-hooks';
import { render } from 'react-dom';
import {BrowserRouter as Router, Route, Link,Switch} from 'react-router-dom';
import 'bootswatch/dist/flatly/bootstrap.min.css';
import Nav from './components/Nav'
import Home from './components/pages/Home'
import About from './components/pages/About'
import Articles from './components/article/Articles'
import Article from './components/article/Article'
const client = new ApolloClient({
uri: 'url in here'
});
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</Router>
</ApolloProvider>
);
}
render(<App />, document.getElementById('root'));
export default App;
Nav.js component
import React from 'react';
import {BrowserRouter as Link} from 'react-router-dom';
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
Here's where the component should be rendered
</div>
</div>
</div>
)
}
I don't know about Apollo but I think you should move your routes from the App component to the Nav component, so the code would be:
App component:
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
</div>
</Router>
</ApolloProvider>
);
}
And the Nav component:
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</div>
</div>
)
}
Don't forget to move imports from App to Nav as well.
my name Rajdeep Singh. I'm using react-router-dom in my react project. when clicking on the Link tag, Link tag not work.im don't understand why not working.
in-browser change URL but a component, not change on the web app
check my code
This my Main.js Component file code
import React, { Fragment } from 'react';
import Foot from './Footer';
import Head from './Header'
import MainContect from './MainContect';
import About from './page/About';
import Book from './page/Book'
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function Main() {
return (
// use Fragment
<Fragment>
{/* use BrowserRouter as Router */}
<Router>
{/* out Router use Head componet */}
<Head />
{/* use Switch tag */}
<Switch>
{/* use Route defined Router path */}
<Route path="/" exact >
{/* compnent name */}
<MainContect />
</Route>
<Route path="/book" >
<Book />
</Route>
<Route path="/about" >
<About />
</Route>
</Switch>
{/* out Router use Head componet */}
<Foot />
</Router>
</Fragment>
)
}
export default Main
This my Header.js component file code
import React from 'react';
import './css/header.scss';
import { BrowserRouter as Router, Link } from 'react-router-dom';
function Head() {
return (
// Use Router tag wrap all Link in Router
<Router>
<header>
<h1 className='logo'> Sikh Book</h1>
<div className="iconArea">+</div>
<ul className="ulArea">
<li>
{/* Use Link tag for navigation */}
<Link to="/"> Home </Link> </li>
<li>
<Link to="/book">
Book
</Link>
</li>
<li>
<Link to="/about">
About
</Link>
</li>
</ul>
</header>
</Router>
)
}
export default Head
Plz tell whats my mistake
thank for helping me
You should initiate the BrowserRouter only once. I'd do this at a high level of your component tree. You could look at this example.
// BrowserRouter is the router implementation for HTML5 browsers (vs Native).
// Link is your replacement for anchor tags.
// Route is the conditionally shown component based on matching a path to a URL.
// Switch returns only the first matching route rather than all matching routes.
import {
BrowserRouter as Router,
Link,
Route,
Switch,
} from 'react-router-dom';
import React from 'react';
const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;
// We give each route either a target `component`, or we can send functions in `render` or `children`
// that return valid nodes. `children` always returns the given node whether there is a match or not.
const App = () => (
<Router>
<div>
<Link to="/">Home</Link>{' '}
<Link to={{pathname: '/about'}}>About</Link>{' '}
<Link to="/contact">Contact</Link>
<Switch>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
<Route
path="/contact"
render={() => <h1>Contact Us</h1>} />
<Route path="/blog" children={({match}) => (
<li className={match ? 'active' : ''}>
<Link to="/blog">Blog</Link>
</li>)} />
<Route render={() => <h1>Page not found</h1>} />
</Switch>
</div>
</Router>
);
Credits to: siakaramalegos