How can I make the 404 route work in React-Router? - node.js

I am trying to make a 404 route with react-router and it doesn't work.
I tried <Route path="*" component={PageNotFound} /> and <Route component={PageNotFound} /> and wrapped all my routes with <Switch></Switch.
My guess is that it doesn't work because I have two <Switch /> components nested inside each other.
App.js:
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Header />
<Switch>
<Route exact path="/" component={Landing} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:id" component={Profile} />
<Switch>
<PrivateRoute exact path="/dashboard" component={Dashboard} />
</Switch>
<Switch>
<PrivateRoute exact path="/posts" component={Posts} />
</Switch>
<Switch>
<PrivateRoute exact path="/post/:id" component={Post} />
</Switch>
<Switch>
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
</Switch>
<Switch>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
</Switch>
<Route path="*" component={PageNotFound} />
</Switch>
<Footer />
</div>
</Router>
</Provider>
);
}
}
PrivateRoute.js:
const PrivateRoute = ({ component: Component, auth, ...rest }) => (
<Route
{...rest}
render={props =>
auth.isAuthenticated === true ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
I also tried putting the 404 route just above the first <PrivateRoute />. And it works for the non-private routes but I want it to work in all routes.
The example above also messes up the <PrivateRoute exact path="/posts" component={Posts} /> route.
You can view the website at https://floating-waters-33077.herokuapp.com

I think the issue is the number of Switch blocks you have. You should ideally only have one.
Since each route is exact you can condense your Switch component children to
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Header />
<Switch>
<Route exact path="/" component={Landing} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:id" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute exact path="/posts" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<Route component={PageNotFound} />
</Switch>
<Footer />
</div>
</Router>
</Provider>
);
}
}
This will allow for the 404 page to be a catch-all if none of the routes match in the overall Switch block.

Related

CoreUI react dashboard routes not working unable to get the nav links

Hi i have downlaoded first time coreui react dashboard. I am unable to get the nav links in it.
App.js Before
<BrowserRouter>
<Suspense fallback={loading}>
<Routes>
<Route exact path="/" name="Home" element={<Home />} />
<Route exact path="/test" name="Test" element={<Test />} />
<Route exact path="/admin" name="Admin" element={<Login />} />
{/* <Route exact path="/register" name="Register Page" element={<Register />} />*/}
<Route exact path="/404" name="Page 404" element={<Page404 />} />
<Route exact path="/500" name="Page 500" element={<Page500 />} />
<Route exact path="/all-products" name="All Products" element={<AllProductsPage />} />
<Route exact path="/deals" name="Deals" element={<Deals />} />
<Route exact path="/product-info" name="Product Information" element={<ProductInfo />} />
<Route path="*" name="Dashboard" element={<DefaultLayout />} />
</Routes>
</Suspense>
</BrowserRouter>
It was working fine but when i changed the path "*" to /dashboard now the dashboard nav links not working anymore
App.js After
<BrowserRouter>
<Suspense fallback={loading}>
<Routes>
<Route exact path="/" name="Home" element={<Home />} />
<Route exact path="/test" name="Test" element={<Test />} />
<Route exact path="/admin" name="Admin" element={<Login />} />
{/* <Route exact path="/register" name="Register Page" element={<Register />} />*/}
<Route exact path="*" name="Page 404" element={<Page404 />} />
<Route exact path="/500" name="Page 500" element={<Page500 />} />
<Route exact path="/all-products" name="All Products" element={<AllProductsPage />} />
<Route exact path="/deals" name="Deals" element={<Deals />} />
<Route exact path="/product-info" name="Product Information" element={<ProductInfo />} />
<Route path="/dashboard" name="Dashboard" element={<DefaultLayout />} />
</Routes>
</Suspense>
Nav Routes Code
<Routes>
{routes.map((route, idx) => {
return (
route.element && (
<Route
key={idx}
path={route.path}
exact={route.exact}
name={route.name}
element={<route.element />}
/>
)
)
})}
<Route path="/dashboard" element={<Navigate to="dashboard" replace />} />
</Routes>
Kindly guide me anyone to resolve the issue thank you.

Provider.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object

When I try to run the website it shows the error in the this line and says it is not valid
ReactDOM.render(<App />, document.getElementById("root"));
Here is the App component in App.js file
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<SideBar />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/signup" component={Signup} />
<Route exact path="/login" component={Login} />
<Route exact path="/dashboard" component={Dashboard} />
<Route exact path="/dashboard/course" component={Course} />
<Route
exact
path="/dashboard/course/lectures"
component={Lecture}
/>
<Route
exact
path="/dashboard/course/discussion"
component={Discussion}
/>
<Route component={NotFound} />
</Switch>
<DeletePopup />
</Router>
</Provider>
);
}
}

White page react-router-dom

I'm having a problem using the Router components with history prop on my react app, Whenever i want to move between pages i have a white page.
Route it's supposed to listen to my history changes
<Router history={history}>
<div>
<Switch>
<PrivateRoute exact path="/" component={Home} />
<Route path="/signin" component={SignIn} />
<Route path="/signup" component={SignUp} />
<Redirect from="*" to="/" />
</Switch>
</div>
</Router>
Try this
<Router history={history}>
<div>
<Switch>
<PrivateRoute exact path="/" component={<Home />} />
<Route path="/signin" component={<SignIn />} />
<Route path="/signup" component={<SignUp />} />
<Redirect from="*" to="/" />
</Switch>
</div>
</Router>

How to set redirect?

I have Switch component
<Switch>
<Route path="/contacts" exact>
<ContactsPage />
</Route>
<Route path="/add" exact>
<AddContactForm />
</Route>
<Redirect to="/contacts" />
</Switch>
Now when I go to /contacts/add it redirects me to /contacts.
But I need to do redirect only if no one of routes is true.
So how to do that?
You need to write whole route not only /add -> /contact/add
<Switch>
<Route path="/contacts/add" exact>
<AddContactForm />
</Route>
<Route path="/contacts" exact>
<ContactsPage />
</Route>
<Redirect to="/contacts" />
</Switch>
Or if you want to split global router to few small routers
// Router.js
<Switch>
<Route path="/contacts"> // remove exact
<ContactsPage />
</Route>
<Redirect to="/contacts" />
</Switch>
then inside Contacts page:
// ContactsPage.js
<Switch>
<Route path="/contacts/add" exact>
<AddContactForm />
</Route>
<Route path="/contacts" exact>
<Contacts />
</Route>
</Switch>

Load different routes on beta server than on main server?

I'm using react and react-router-dom for my website. I have two versions of the site, one that it for beta users and the other that is for my customers. When the site is loaded on the beta server with process.env.IS_BETA === "true" I only want users to be able to access the login and forgot my password pages. I don't want them to access the registration page or the front page. I tried the following but it didn't work because I think the process.env is already read when it's built.
export const App = () => (
<BrowserRouter>
<div className="d-flex flex-column height-100vh">
<Navbar />
{process.env.IS_BETA === "true" && (
<Switch>
<Route path="/PrivacyPolicy" component={PrivacyPolicy} />
<Route path="/TermsOfUse" component={TermsOfUse} />
<Route path="/Login" component={Login} />
<Route path="/Forgot" component={Forgot} />
<Route path="/Reset" component={Reset} />
<Redirect to="/Login" />
</Switch>
)}
{process.env.IS_BETA !== "true" && (
<Switch>
<Route exact path="/" component={Home} />
<Route path="/PrivacyPolicy" component={PrivacyPolicy} />
<Route path="/TermsOfUse" component={TermsOfUse} />
<Route path="/Register" component={Register} />
<Route path="/Login" component={Login} />
<Route path="/Forgot" component={Forgot} />
<Route path="/Reset" component={Reset} />
<Redirect to="/" />
</Switch>
)}
<Footer />
</div>
</BrowserRouter>
);
How do I redirect or not load some pages on the beta server?
process.env is not available direclty in your Javascript code, but it will be available to Webpack at compile time. Webpack supports defining globals within your Javascript environment with the DefinePlugin, so by adding a new plugin definition as follows:
plugins: [
new webpack.DefinePlugin({
__IS_BETA__: process.env.IS_BETA === "true",
}),
],
in your Webpack config, __IS_BETA__ will be replaced throughout your Javascript code based on whether IS_BETA environment variable was set to true when compiling your app.
You can then reference it in your React code as such:
export const App = () => (
<BrowserRouter>
<div className="d-flex flex-column height-100vh">
<Navbar />
{__IS_BETA__ && (
<Switch>
<Route path="/PrivacyPolicy" component={PrivacyPolicy} />
<Route path="/TermsOfUse" component={TermsOfUse} />
<Route path="/Login" component={Login} />
<Route path="/Forgot" component={Forgot} />
<Route path="/Reset" component={Reset} />
<Redirect to="/Login" />
</Switch>
)}
{!__IS_BETA__ && (
<Switch>
<Route exact path="/" component={Home} />
<Route path="/PrivacyPolicy" component={PrivacyPolicy} />
<Route path="/TermsOfUse" component={TermsOfUse} />
<Route path="/Register" component={Register} />
<Route path="/Login" component={Login} />
<Route path="/Forgot" component={Forgot} />
<Route path="/Reset" component={Reset} />
<Redirect to="/" />
</Switch>
)}
<Footer />
</div>
</BrowserRouter>
);

Resources