I am building a website with react and I created a navbar which was printed onto the react app on my local server. But i need the login page to show before the navbar and all the other pages show.
Here is my app.js
import './App.css';
import Navbar from './components/navbar';
import Login from './pages/login';
import Onboarding from './pages/onboarding';
import Training from './pages/training';
import Contract from './pages/contract';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
function App() {
return (
<div className="App">
<Router>
<Login />
<Route path= "/login" exact component={Login} />
<div>
<Routes>
<Navbar/>
<Route path = "/customer info" exact component={Navbar}/>
<Route path = "/onboarding" exact component={Onboarding}/>
<Route path = "/training material" exact component={Training}/>
<Route path = "/contract" exact component={Contract}/>
</Routes>
</div>
</Router>
</div>
);
}
export default App;
before i added a path for login to appear before navbar it was working fine. fine as in it was rendering when i typed npm start.
here is my login.js
// import React, {useState} from 'react';
import React from 'react';
import Logo from '../assets/BackBar_Logo_2-05.png';
import {Link } from 'react-router-dom';
import '../styles/login.css'
function login() {
return (
<div className = "background">
<div>
<img src ={Logo} alt = "backbar logo"/>
</div>
<div>
<h1>Customer Portal</h1>
<br></br>
<h3>Login</h3>
<form action = "submission.html" method = "POST">
<section>
<label for = "username">Username/email</label>
<br></br>
<input type = "text" name = "username" placeholder= "username" required/>
</section>
<section>
<label for = "password">Password</label>
<br></br>
<input type="text" name="password" placeholder="password" reqiured/>
</section>
<Link to = "/customer info" >
<button>Login</button>
</Link>
<Link to = "/sign up">
<button>Sign Up</button>
</Link>
</form>
</div>
</div>
)
}
export default login
CodePudding user response:
You are using react-router 6 right? A Route is only ever to be used as the child of Routes element, never rendered directly. Please wrap your Route in a Routes.
CodePudding user response:
You may need to use Routes as the answerer above said. Also, if you want the login to be rendered first by default you need to make the path for the login "/" rather than "/login", so it is the root path of the app, or redirect calls to "/" to go to "/login". Like this example from the react router docs:
<Route exact path="/"><Redirect to="/dashboard" /></Route>
If you then want to go further and block of the rest of the app from being used until login is complete, you will need to create some sort of login token and check the value of that to determine whether to render the content of the other paths. You can do this using local storage /session storage if this is just a super simple practice app but JWT if you want some actual security: https://www.youtube.com/watch?v=27KeYk-5vJw
Edit: You can also use the same redirect as shown above to redirect to an error page if the user isn't logged in:
<Route exact path="/">{loggedIn ? <Redirect to="/dashboard" />: <PublicHomePage /></Route>
CodePudding user response:
All Routes defined have to be within a Routes
component. Furthermore, it's not good to put the Navbar
component inside the Routes
component, because it would unnecessarily rerender every time you switch to another route.
Do it like the following:
function App() {
return (
<div className="App">
<Router>
<Navbar/>
<Routes>
<Route path= "/login" exact component={Login} />
<Route path = "/customer info" exact component={Navbar}/>
<Route path = "/onboarding" exact component={Onboarding}/>
<Route path = "/training material" exact component={Training}/>
<Route path = "/contract" exact component={Contract}/>
</Routes>
</Router>
</div>
);
}
To redirect the user to the login page if he's not logged in, you have to introduce private/protected routes. A great article to follow along you can find here.