I created my page routing with react-router v5 and everything works well. If I click on the link, it takes me to the page, but when I reload the page I get a "404 | Page Not Found" error on the page.
import React, { useEffect, useState } from 'react'
import Home from './dexpages/Home'
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
import Dashboard from './dexpages/dashboard';
import Swapping from './dexpages/swapping'
import Send from './dexpages/send';
import Airdrops from './dexpages/airdrops'
function Main() {
const [mounted, setMounted] = useState(false)
useEffect(() => {
if (typeof window !== "undefined") {
setMounted(true)
}
}, [])
return (
<>
{mounted &&
<BrowserRouter>
<div className="min-h-screen" style={{ overflowX: 'hidden' }}>
<Routes>
<Route path="/airdrops" element={<Airdrops />} />
<Route path="/send" element={<Send />} />
<Route path="/swap" element={<Swapping />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/" element={<Home />} />
</Routes>
</div>
</BrowserRouter>
}
</>
)
}
export default Main;
This is my Main Component where I create all the routing.
This is the error I'm getting when I reload the page
Don't use React Router with next.js.
Next.js has its own routing mechanism which is used for both client-side routing and server-side routing.
By using React Router, you're bypassing that with your own client-side routing so when you request the page directly (and depend on server-side routing) you get a 404 Not Found.
Next.js has a migration guide.
Your paths need to be adjusted. For the home page it is fine to be routed to / however for the other pages there is no need for a backslash, remove the backslash from the Airdrops, Send, Swapping, and Dashboard paths respectively and you should be fine.
Try this below for each of the routes.
<Route path="airdrops" element={<Airdrops />} />
<Route path="send" element={<Send />} />
<Route path="swap" element={<Swapping />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="/" element={<Home />} />
Related
I am encountering a problem with my private routing setup. Currently, I use the user variable in the App.js to determine if a user is logged in or not, in order to restrict access to private routes. The issue with this method is that if a user attempts to directly access a private page (such as "mysolutions"), they will be immediately redirected to the homepage due to the delay in fetching the user data from the database during the initial website load.
I would like to know how can I fix this issue.
My App.js code:
import React, { Suspense } from "react"
import { Navigate, Route, Routes } from "react-router-dom"
import rocketLoader from "./assets/animated_illustrations/rocketLoader.json"
import Layout from "./components/layouts/Layout"
import Meta from "./components/meta/Meta"
import LottieAnimation from "./components/reusable/LottieAnimation"
import ScrollToTop from "./components/reusable/ScrollToTop"
import { useAuthContext } from "./hooks/useAuthContext"
import "./App.css"
// lazy loading components
const Homepage = React.lazy(() => import("./pages/Homepage"))
const Dashboard = React.lazy(() => import("./pages/Dashboard"))
const MySolutions = React.lazy(() => import("./pages/MySolutions"))
const App = () => {
const { authIsReady, user } = useAuthContext()
return (
<>
<Meta routes={routes} />
<div>
<Suspense
fallback={
<div className="flex justify-center items-center min-h-screen">
<LottieAnimation animationDataFile={rocketLoader} />
</div>
}
>
<ScrollToTop>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Homepage />} />
<Route path="challenges" element={<Dashboard />} />
<Route
path="mysolutions"
element={user ? <MySolutions /> : <Navigate to="/" />}
/>
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Routes>
</ScrollToTop>
</Suspense>
</div>
</>
)
}
export default App
You can use authIsReady variable from useAuthContext() for check the current user data inside the private route.
And with this variable you can simply add if condition to private route like :
<ScrollToTop>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Homepage />} />
<Route path="challenges" element={<Dashboard />} />
{authIsReady && (
<Route
path="mysolutions"
element={user ? <MySolutions /> : <Navigate to="/" />}
/>
)}
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Routes>
</ScrollToTop>
I would create a loading page, which is shown to the user until the fetch is completed and we are able to decide if we can let advance to the private route or not. Would this solution work for you?
I have an authentication system, and I want to show different <Routes> with different available paths considering from login state.
I uesd <Navigate/> element for redirection from hidden pages depending login state. But there is a problem. <Navigate/> redirects without considering the state.
For example, when I logged in and try to open Login page I must redirects to a Main page, and when I don't logged in and try to open profile I must redirect to Login Page. And when I try to open any of this pages I automaticly redirects to Main page.
routes.jsx:
import React from 'react';
import {
Routes,
Route,
Navigate
} from 'react-router-dom';
import Profile from './pages/Profile/Main/Profile';
import Login from './pages/Auth/Login/Login';
import Register from './pages/Auth/Register/Register';
import Main from './pages/Main/Main';
import { Loans } from './pages/Profile/Active/Loans';
import ErrorPage from './pages/errorPage/ErrorPage';
export const useRoutes = isAuthenticated => {
if(isAuthenticated){
return (
<Routes>
<Route path='/profile' exact>
<Route index path=":id" element={<Profile/>}/>
<Route path="loans" element={<Loans/>} exact/>
</Route>
<Route path='/' exact element={<Main/>}/>
<Route
path="*"
element={<ErrorPage/>}
/>
<Route
path="/auth/*"
element={<Navigate to="/" replace />}
/>
</Routes>
);
} else {
return (
<Routes>
<Route path='/auth' exact>
<Route path='login' element={<Login/>} exact />
<Route path="register" exact element={<Register/>}/>
<Route
path=""
element = {
<Navigate to="login" replace />
}
/>
</Route>
<Route path='/' exact element={<Main/>}/>
<Route
path="/profile/*"
element={<Navigate to="/auth/login" replace />}
/>
<Route
path="*"
element={<ErrorPage/>}
/>
</Routes>
)
}
}
App.jsx:
import {
BrowserRouter
} from 'react-router-dom';
import {useRoutes} from './routes';
import 'materialize-css';
import { useAuth } from './hooks/auth.hook';
import { AuthContext } from './context/auth.context';
function App() {
const {token, userId, login, logout} = useAuth();
const isAuthenticated = !!token;
const routes = useRoutes(isAuthenticated);
return (
<AuthContext.Provider value = {{
token, login, logout, userId, isAuthenticated
}}>
<BrowserRouter>
<div className="container">
{routes}
</div>
</BrowserRouter>
</AuthContext.Provider>
);
}
export default App;
One issue that may be causing this is you check authentication based on whether the token exists. Debug the output of that variable to see if it is cleared correctly when you log out. Next, you are determining authentication once inside of App(), fetching the routes from useRoutes(), and then rendering the app without ever checking again if the authentication is still valid. A better approach would be something like this:
const auth = useAuth();
return ({auth.isAuthenticated ? (
<Fragment>
<Link to="/account">Account ({auth.user.email})</Link>
<Button onClick={() => auth.signout()}>Signout</Button>
</Fragment>
) : (
<Link to="/signin">Signin</Link>
)});
So I'm using react router v6 in my React App.
I have the following routes enabled in my app.js file
<Routes>
<Route path='/' component={<Home />} />
<Route path='/login' component={<SignUp />} />
<Route path='/signup' component={<Login />} />
</Routes>
Everything's fine and that. What I want to to do is to put restriction on pages. Now I know how to create PrivateRoutes and PublicRoutes based on LoggedIn User.
For this purpose I want the user to not be able to access Homepage after he or she signups.
Are there an functions for that or what strategy would I use.
I accomplished this using 'react-router-dom' and creating a PrivateRoute component. The following code is not tested but can give you some ideas. LoaderComponent is a loading animation of your choice can be toher component as well.
// Based on https://reactrouter.com/web/example/auth-workflow
// If the user is not yet authenticated.
const PrivateRoute: React.FC<PrivateRouteProps> = ({ children, path, ...props }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
//put your authentication logic
setIsAuthenticated(true);
}, []);
return (
<Route
path={path}
{...props}
render={() => (isAuthenticated ? children : <LoaderComponent />)}
/>
);
};
And in your router config
import { Switch } from 'react-router-dom';
<Switch>
<PrivateRoute exact path='/'>
<Home />
</PrivateRoute>
...
</Switch>
Here is my code, I am completely new to front end development can any one help me solve the issue, I want the user to be redirected to the login page if the user is not logged in but once he is logged in every thing should work fine but even when I click sign in, the login page shows up when I change the URL, The login page is appearing on every URL
Here's my code (i am new to front end pls dont judge)
import { useState } from 'react'
import { Route, Switch} from 'react-router-dom'
import Dashboard from "./pages/Dashboard";
import DatasetGenerator from "./pages/DatasetGenerator"
import Simulator from "./pages/Simulator"
function App() {
const [login, setlogin] = useState(true)
const [homepage, setHomepage] = useState(false)
const loginHandler = ()=>{
if(login == true){setlogin(false)
setHomepage(true)}
}
return (
<div>
{login && <SignIn loginHandler={loginHandler} />}
<Switch>
<Route path='/' exact>
{homepage && <Dashboard />}
</Route>
<Route>
{homepage && <DatasetGenerator path="/dataset-generator"/>}
</Route>
<Route path="/simulator">
{homepage && <Simulator />}
</Route>
</Switch>
</div>
)
}
export default App;
Seems like you want to conditionally render the login component OR the rest of your app. Since the login state and the homepage state appear to be mutually exclusive you probably don't need both (though perhaps we're missing some context).
return (
<div>
{login ? (
<SignIn loginHandler={loginHandler} />
) : (
<Switch>
<Route path='/' exact>
<Dashboard />
</Route>
<Route>
<DatasetGenerator path="/dataset-generator"/>
</Route>
<Route path="/simulator">
<Simulator />
</Route>
</Switch>
)}
</div>
)
A better solution would be to implement an auth workflow by creating authenticated route components that handle redirecting to a login route if not authenticated, otherwise allows the user to access the route.
I'm using react router dom v5 with material ui, and I have my routes in the following way:
import React from 'react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Layout from '../components/layout'
import Login from '../screens/Login'
import NotFound from '../screens/NotFound'
import routes from './routes'
const DynamicRoutes = () => {
return (
<>
{Object.values(routes).map(({ component, path }) => (
<Route exact path={path} key={path} component={component} />
))}
</>
)
}
const Router = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login} />
<Layout>
<DynamicRoutes />
</Layout>
<Route path="*" component={NotFound} />
</Switch>
</BrowserRouter>
)
}
export default Router
I have already tried with <Route component={NotFound} />, and neither worked to me. Can anyone help me? The rest of routes work correctly, but when I type a fake route, doesn't go to the NotFound screen.
That occurs because all children of a <Switch> should be <Route> or <Redirect> elements.
You can check more about it in react-router-dom docs.
So, one solution for your code would be do something like that:
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login} />
{Object.values(routes).map(({ Component, path }) => (
<Route exact path={path} key={path}>
<Layout>
<Component />
</Layout>
</Route>
))}
<Route path="*" component={NotFound} />
</Switch>
</BrowserRouter>
*For your routes object array, Component property must be with an upper C.
You can check this sample code.