React Router not Working in production build - reactjs

I am having a react-router problem in production build. Every thing works fine in development, but whenever I build a production using npm run build and then open the index.html file in the build folder, I only get the Header and Footer portion of the website, and when I try navigating to the links on the header I get an error that says "your file could not be accessed". Navigating to the Home link takes me to the c: directory on computer instead of just reloading the page I was on.
I have no idea what's going on. But I believe it might be from the Router.
Thank you.
Here is the code:
router.js
import {
BrowserRouter,
Routes,
Route,
} from 'react-router-dom';
import Home from '../components//pages/home';
import Infra from '../components/pages/infra';
import Outreach from '../components/pages/outreach';
import AboutUs from '../components/pages/aboutUs';
import ProgressOfWork from '../components/pages/progressOfWork';
const Router = () =>
<BrowserRouter basename=''>
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="infra" element={<Infra />} />
<Route path="outreach" element={<Outreach />} />
<Route path="aboutUs" element={<AboutUs />} />
<Route path="progressOfWork" element={<ProgressOfWork />} />
</Routes>
</BrowserRouter>
export default Router;
App.js
import Router from './routes/routes';
import Header from './utilities/header';
import Footer from './utilities/footer';
function App() {
return (
<div>
<Header />
<Router />
<Footer />
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

Related

React Js showing Blank Screen

I tried many different ways including having baseline on BrowserRouter and add line, initially I was using Switch but soon realised that npm 6.0 onwards has changed it to Routes, so I downgrade it to npm 5.2.3. However, a blank screen still persists.
Hope to get suggestions from the experts here
this is my App.js
import logo from './logo.svg';
import './App.css';
import {Home} from './Home';
import {Department} from './Department';
import {Employee} from './Employee';
import {Navigation} from './Navigation';
import { BrowserRouter, Switch, Route } from "react-router-dom";
function App() {
return (
<BrowserRouter basename='/index.html'>
<div className="container">
<h3 className="m-3 d-flex justify-content-center">
React JS Tutorial
</h3>
<Navigation/>
<Switch>
<Route path='/' component={Home} exact/>
<Route path='/department' component={Department}/>
<Route path='/employee' component={Employee}/>
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
This is index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
reportWebVitals();
I remember running into this issue, try the code, it might not work but I think you can't have any other component within BrowserRouter, hopefully that gives you at least a direction.
function App() {
return (
<BrowserRouter basename='/index.html'>
<Switch>
<Route path='/' component={Home} exact/>
<Route path='/department' component={Department}/>
<Route path='/employee' component={Employee}/>
</Switch>
</BrowserRouter>
);
}

Why i have an error when rendering components outside router? [duplicate]

I have a navbar that is rendered in every route while the route changes on click.
./components/navbar.jsx
import React, { Component } from 'react';
import '../App.css';
import { Link } from 'react-router-dom';
class Navbar extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div id = 'navbar'>
<div className='name-head'>
My Name
</div>
<div id = 'nav-links-container'>
<Link to='/experiences'>
<div className = 'nav-links'>
Experiences
</div>
</Link>
<div className = 'nav-links'>
Projects
</div>
<div className = 'nav-links'>
Skills
</div>
<div className = 'nav-links'>
Resume
</div>
</div>
</div>
);
}
}
export default Navbar;
./components/experiences.jsx
import React, { Component } from 'react';
class Experiences extends Component {
render() {
return (
<div>
<h1>hi</h1>
</div>
);
}
}
export default Experiences;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Navbar from './components/Navbar';
import Home from './components/Home';
import Experiences from './components/experience';
import {
BrowserRouter as Router,
Routes,
Route
} from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Navbar />
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
The error doesn't come when I remove the <Link> from the experiences tag in navbar.
There is a similar question posted here: Error: useHref() may be used only in the context of a <Router> component
but doesn't help.
I'm using react router v6
Issue
You are rendering the navbar outside the routing context. The Router isn't aware of what routes the links are attempting to link to that it is managing. The reason routing works when directly navigating to "/experiences" is because the Router is aware of the URL when the app mounts.
<Navbar /> // <-- outside router!!
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
Solution
Move it inside the routing context so the Router is aware and can manage routing correctly.
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
react-router-dom#6.4 Data APIs
If you are using the new Data routers you can hit this issue if you attempt to render a header/navbar outside the RouterProvider component. For this you can create a layout route that is part of the routing configuration passed to createBrowserRouter (and other variants).
Example:
const AppLayout = () => (
<>
<Navbar />
<Outlet />
</>
);
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<AppLayout />}>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Route>
)
);
...
<RouterProvider router={router} />
in React Route v6 you can solve this giving the route context to your entire App with <BrowserRouter>
This is an complete example of index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { App } from './components/App/App.jsx';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter> //that is the key
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
If you are still having problem with this one, it is because react-router-dom relies on React context to work when you try to unit-test it. This makes <Link /> or <Route /> obsolete.
Try reading the react-router-dom documentation.
Instead of using
render(<Example />)
that have either or inside it, you can try
render(<MemoryRouter>
<Example />
</MemoryRouter>)
Hope this solves your problem
In react-router-dom:6.x and react:18.x, we should use the Router in the following way to resolve the issue:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { App } from './App.js';
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Router> // Router
<App /> // Application
</Router>
</React.StrictMode>
);
Links are inside Navbar &
Navbar is outside of Router
=> links are outside of Router => Router will not manage Links
Solution
Move the Navbar into Router section. Example:
<Router>
<Navbar /> // <===========
<Routes>
<Route />
<Route />
</Routes>
</Router>
Wrap navbar with BrowserRouter
import { BrowserRouter, Routes, Route } from "react-router-dom";
<BrowserRouter>
<AppNavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/wall" element={<WallPost />} />
</Routes>
</BrowserRouter>
Install in your project React Router v6.
npm install react-router-dom#6
Then use BrowserRouter in your index.js file, below like this:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
React Router v6 this problem common one, you can simply replace "index.js" code. you will got solution-
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
This error happens because Link component needs to reach out to react-router context object. Your Navbar component is using Link component but Navbar is not wrapped by router context.
A similar error happens in a testing environment. If you have a component that uses Link component and if you render this component in a testing environment, you will get the same error because Link component needs to access a router context. In the case of test environment:
import { render } from "#testing-library/react";
// this will throw same error
test("testing", () => {
render(<ComponentRendersLink/>);
});
Solution in this case to wrap it with a router
// there are more router options
import { MemoryRouter } from "react-router-dom";
render(
<MemoryRouter>
<ComponentRendersLink />
</MemoryRouter>
);
This is very much an edge case, but in my case it turned out a lib I develop had react-router-dom: 6.0.2 installed and project that uses it v6.3.0
Your links just needs to be within a BrowserRouter component since you use v6
After importing
<BrowserRouter>
<Link to='page'>
</BrowserRouter>

Error: useHref() may be used only in the context of a <Router> component. It works when I directly put the url as localhost:3000/experiences

I have a navbar that is rendered in every route while the route changes on click.
./components/navbar.jsx
import React, { Component } from 'react';
import '../App.css';
import { Link } from 'react-router-dom';
class Navbar extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div id = 'navbar'>
<div className='name-head'>
My Name
</div>
<div id = 'nav-links-container'>
<Link to='/experiences'>
<div className = 'nav-links'>
Experiences
</div>
</Link>
<div className = 'nav-links'>
Projects
</div>
<div className = 'nav-links'>
Skills
</div>
<div className = 'nav-links'>
Resume
</div>
</div>
</div>
);
}
}
export default Navbar;
./components/experiences.jsx
import React, { Component } from 'react';
class Experiences extends Component {
render() {
return (
<div>
<h1>hi</h1>
</div>
);
}
}
export default Experiences;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Navbar from './components/Navbar';
import Home from './components/Home';
import Experiences from './components/experience';
import {
BrowserRouter as Router,
Routes,
Route
} from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Navbar />
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
The error doesn't come when I remove the <Link> from the experiences tag in navbar.
There is a similar question posted here: Error: useHref() may be used only in the context of a <Router> component
but doesn't help.
I'm using react router v6
Issue
You are rendering the navbar outside the routing context. The Router isn't aware of what routes the links are attempting to link to that it is managing. The reason routing works when directly navigating to "/experiences" is because the Router is aware of the URL when the app mounts.
<Navbar /> // <-- outside router!!
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
Solution
Move it inside the routing context so the Router is aware and can manage routing correctly.
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
react-router-dom#6.4 Data APIs
If you are using the new Data routers you can hit this issue if you attempt to render a header/navbar outside the RouterProvider component. For this you can create a layout route that is part of the routing configuration passed to createBrowserRouter (and other variants).
Example:
const AppLayout = () => (
<>
<Navbar />
<Outlet />
</>
);
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<AppLayout />}>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Route>
)
);
...
<RouterProvider router={router} />
in React Route v6 you can solve this giving the route context to your entire App with <BrowserRouter>
This is an complete example of index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { App } from './components/App/App.jsx';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter> //that is the key
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
If you are still having problem with this one, it is because react-router-dom relies on React context to work when you try to unit-test it. This makes <Link /> or <Route /> obsolete.
Try reading the react-router-dom documentation.
Instead of using
render(<Example />)
that have either or inside it, you can try
render(<MemoryRouter>
<Example />
</MemoryRouter>)
Hope this solves your problem
In react-router-dom:6.x and react:18.x, we should use the Router in the following way to resolve the issue:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { App } from './App.js';
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Router> // Router
<App /> // Application
</Router>
</React.StrictMode>
);
Links are inside Navbar &
Navbar is outside of Router
=> links are outside of Router => Router will not manage Links
Solution
Move the Navbar into Router section. Example:
<Router>
<Navbar /> // <===========
<Routes>
<Route />
<Route />
</Routes>
</Router>
Wrap navbar with BrowserRouter
import { BrowserRouter, Routes, Route } from "react-router-dom";
<BrowserRouter>
<AppNavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/wall" element={<WallPost />} />
</Routes>
</BrowserRouter>
Install in your project React Router v6.
npm install react-router-dom#6
Then use BrowserRouter in your index.js file, below like this:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
React Router v6 this problem common one, you can simply replace "index.js" code. you will got solution-
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
This error happens because Link component needs to reach out to react-router context object. Your Navbar component is using Link component but Navbar is not wrapped by router context.
A similar error happens in a testing environment. If you have a component that uses Link component and if you render this component in a testing environment, you will get the same error because Link component needs to access a router context. In the case of test environment:
import { render } from "#testing-library/react";
// this will throw same error
test("testing", () => {
render(<ComponentRendersLink/>);
});
Solution in this case to wrap it with a router
// there are more router options
import { MemoryRouter } from "react-router-dom";
render(
<MemoryRouter>
<ComponentRendersLink />
</MemoryRouter>
);
This is very much an edge case, but in my case it turned out a lib I develop had react-router-dom: 6.0.2 installed and project that uses it v6.3.0
Your links just needs to be within a BrowserRouter component since you use v6
After importing
<BrowserRouter>
<Link to='page'>
</BrowserRouter>

Deploy React JS project in AWS S3 without involved AWS CDN

Is it possible to host React JS/ Node JS project inside the AWS S3 without using AWS CDN because my CDN is currently hosted at Cloudflare and it can be a problem to migrate my DNS to AWS DNS.
I have attempted to setup a AWS S3 bucket and set it as static hosting purpose and generate production build from my React JS project.
But I keep enouncter access denied error when I accessed the generated AWS S3 bucket hostname.
May I know how can I resolve this?
I have followed this resource.
But my React App still not working properly. If it is working properly, it should redirect me to https://s3.hosting.com/ with present the view that I specify in the react router.
Below are my code snippet for index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
let app = document.getElementById('root');
history.listen(location => {
const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
if (path) {
setTimeout(() => {
history.replace(path);
}, 100);
}
});
// 2. Render our app
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,app);
reportWebVitals();
Below are my code snippet for App.js
import './react-datepicker.css';
import './App.css';
import React, {Component} from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import ViewOrder from "./components/vieworder";
import CreateOrder from './components/createorder';
import ViewAllOrder from "./components/viewallorder";
import ViewRestaurant from "./components/restaurant";
import ViewBranches from "./components/branch";
import ViewBranchOrder from "./components/viewbranchorder";
import ViewAllConsumer from './components/consumer';
import Auth from "./components/auth";
import Profile from "./components/profile";
import ViewTransaction from "./components/transaction";
import ViewAccessToken from "./components/viewaccesstoken.js";
import NotFoundPage from "./components/notfoundpage";
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.js';
class App extends Component {
render(){
return (
<Router>
<Switch>
<Route exact path="/auth" component={Auth} />
<Route exact path="/" component={Auth} />
<Route exact path="/order" component={ViewAllOrder} />
<Route exact path="/transaction/user/:userId" component={ViewTransaction} />
<Route exact path="/token/:userId" component={ViewAccessToken} />
<Route exact path="/transaction" component={ViewTransaction} />
<Route exact path="/order/v/:orderId" component={ViewOrder} />
<Route exact path="/storeFront/:storefrontToken/order/create" component={CreateOrder} />
<Route exact path="/consumer" component={ViewAllConsumer}/>
<Route exact path="/restaurant" component={ViewRestaurant}/>
<Route exact path="/profile" component={Profile}/>
<Route exact path="/profile/:uid" component={Profile}/>
<Route exact path="/ViewBranches" component={ViewBranches}/>
<Route exact path="/restaurant/:restaurantId/branch" component={ViewBranches}/>
<Route exact path="/restaurant/:restaurantId/branch/:branchId/:branchName/order" component={ViewBranchOrder}/>
<Route exact path="*" component={NotFoundPage}/>
</Switch>
</Router>
);
}
}
export default App;

React : Redirecting to a different page

I want to conditionally redirect to a different page, and here is my code :
render() {
if (this.state.logged) {
return <Redirect to="/admin" />;
}
console.log("Login");
return (
<div style={this.state.body}>
<div style={this.state.box}>
<br />
<br />
{this.getForm()}
<br />
<br />
</div>
</div>
);
}
The issue is when the condition is satisfied and the redirection to admin.jsx should take place
I keep getting this error:
Error: Invariant failed: You should not use <Redirect> outside a <Router>
Here is my app.js
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { link, Switch, Route } from "react-router-dom";
import Login from "./components/Login";
import Logout from "./components/Logout";
import Admin from "./components/Admin";
function App() {
return (
<switch>
<Route exact path="/" component={Login} />
<Route path="/admin" component={Admin} />
<Route path="/user" component={Admin} />
<Route path="/logout" exact component={Logout} />
</switch>
);
}
Here is my index.js:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap.css";
import Login from "./components/Login";
ReactDOM.render(<Login />, document.getElementById("root"));
serviceWorker.unregister();
This is what is being done in the tutorial, and I have absolutely no idea why this is happening.
Please help
You have to wrap your whole application with the Router component provided by react-router-dom. If you try to use any component from that library outside a Router, you will get that error.
Also, this is probably more a matter of preference, but I think I wouldn't render the Login component as the root in the application. I would render the App component and then redirect to the Login if not logged in.
Therefore, you should have something like this in your index.js
import React from "react";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap.css";
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root"));
serviceWorker.unregister();
Wrap your whole App with Router from react-router-dom since it provides the context for Redirection
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { Link, Switch, Route, BrowserRouter as Router } from "react-router-dom";
import Login from "./components/Login";
import Logout from "./components/Logout";
import Admin from "./components/Admin";
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route path="/admin" component={Admin} />
<Route path="/user" component={Admin} />
<Route path="/login" exact component={Login} />
<Route path="/logout" exact component={Logout} />
</Switch>
</Router>
);
}
Render your app here not Login and put your Login inside the Router.
ReactDOM.render(<App />, document.getElementById("root"));

Resources