Create-React-App/React Router Not Working On Deployment via Render - reactjs

Trying to deploy my first React application. The index route is visible but none of the relative endpoints work and I get a 404 from the render server. However I read that I needed to make these changes to the deployment in order for the client-side routing to work properly:
Render's suggestion for configuring client-side routing to work properly
However, when I visit an endpoint like "/login" or "/signup", the react router in my app catches it as a 404 and
renders the 404 page, and the endpoint in the url changes to /index.html
index.js
import React from "react";
import ReactDOM from "react-dom/client";
import Views from "./App";
import { BrowserRouter } from "react-router-dom";
import { UserProvider } from "./context/userContext.js";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<UserProvider>
<BrowserRouter>
<Views />
</BrowserRouter>
</UserProvider>
</React.StrictMode>
);
App.js
import { Routes, Route } from "react-router-dom";
import PublicRoutes from "./routes/PublicRoutes";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { useUser } from "./context/userContext.js";
function Views() {
const { loading } = useUser();
if (loading) return <h1>Loading...</h1>;
return (
<div className="App">
<Routes>
<Route path="*" element={<PublicRoutes />} />
</Routes>
<ToastContainer />
</div>
);
}
export default Views;
Routing Logic:
const PublicRoutes = () => {
return (
<QueryClientProvider client={new QueryClient()}>
<Routes>
<Route index element={<Landing />} />
<Route path="login" element={<Login />} />
<Route path="signup" element={<SignUpMUI />} />
<Route element={<Protect />}>
<Route path="dashboard" element={<Dashboard/>} />
<Route path="event/:id" element={<EventPage />} />
<Route path="profile" element={<>Profile Page</>} />
<Route path="settings" element={<>Settings</>} />
</Route>
<Route path="*" element={<h1>404</h1>} />
</Routes>
</QueryClientProvider>
);
};
export default PublicRoutes;
I thought maybe it has something to do with the file pathing because my repository contains a sub-folder for the API and then a sub-folder for the react application so maybe I thought I had to route the html pathing as /client/index.html or something but that didn't work. Honestly I have no idea what I am supposed to do, I have very little experience with deploying and with most resources and tutorials covering how to deploy with Heroku (which has recently deprecated their free tier) and most tutorials covering React deployment on Render don't involve any usage of the react router.
Also, I would like to reiterate the structure of the repository as it contains two sub folders, one which contains the react application called "client" and another which contains the server code called "server". Here is an image
I'm thinking maybe this has something to do with the redirections to the index.html but Idk, I've already tried messing about with the configuration on render to see if it would make a difference but no dice.

Just read: https://render.com/docs/deploy-create-react-app
and add this to Redirects/Rewrites section
enter image description here

Related

Why is react-router-dom v6 only rendering my landing page?

I know several questions have been asked relating to this, but none capture what I am experiencing so here it goes...
My app loads fine and my landing page is rendering as expected. The weird piece is that none of the other routes are loading. I have a react-router-dom Link on the Landing component that directs to school but nothing happens, no console errors, just the Landing component still rendering. When I manually type any other route in the browser, still nothing happens, just the Landing pages rendering.
It doesn't matter what component is set to the / route, it renders fine but something is definitely up with the react-router-dom.
Here's my index.js
import { render } from 'react-dom';
import App from './components/app/App';
import './index.scss';
render(
<App />,
document.getElementById('root'),
);
App.js
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import Content from '/components/Content';
import Nav from '../nav/Nav';
import Home from '../../pages/home/Home';
import PageFooter from '../footer/PageFooter';
import Search from '../../pages/search/Search';
import Course from '../../pages/course/Course';
import Landing from '../../pages/landing/Landing';
export default function App() {
return (
<div className="App">
<BrowserRouter>
<Nav />
<Content className="main-wrapper" fullWidth>
<Routes>
<Route path="/" element={<Landing />} />
<Route path="school" element={<Home />} />
<Route path="search" element={<Search />} />
<Route path="courses">
<Route path=":courseId" element={<Course />} />
<Route
index
element={<Navigate replace to="/" />}
/>
</Route>
</Routes>
</Content>
<PageFooter />
</BrowserRouter>
</div>
);
}
I am absolutely beside myself - what am I doing wrong?
As it usually goes, this was my error. After ripping it all out, starting with a fresh CRA app, and piecing my project back together, I found that in the <Nav /> component I had an inappropriate math operator (= instead of ===) going on within a useLocation reference 🤦🏽

React-router-dom displays nothing when using 'Route'

I am trying to render an ultra-simple webpage using react-routing-dom lib. Here is my app.js
import React from 'react';
import Nav from './nav.js';
import Shop from './shop.js';
import About from './about.js';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import './App.css';
function App() {
return (
<>
<Nav />
<Router>
<Route exact path='/' element={<About />} />
<Route exact path='/shop' element={<Shop />} />
</Router>
</>
);
}
export default App;
using this, I run npm start and expect that the <Nav /> and <About /> components render at http://localhost:3000. Instead, the screen is completely blank. There are no warnings, errors, etc.; it's a clean build. Not even the <Nav /> component that is outside the entire Router block is rendered!
The plot thickens: when I build and run the following, all three components render.
import React from 'react';
import Nav from './nav.js';
import Shop from './shop.js';
import About from './about.js';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import './App.css';
function App() {
return (
<>
<Nav />
<Router>
<About />
<Shop />
</Router>
</>
);
}
export default App;
From this, I think its safe to assume that <Route /> is the problem.
react-router-dom seems to change a lot in a relatively short amount of time, so there is a lot of outdated info. If someone could point me in the right direction, I would be very grateful indeed.
Only thing I see missing is the Routes component wrapping the Route components. You imported Routes but don't appear to have used it. All Route components must be rendered into a Routes component (or another Route if nesting). Without the Routes you should be seeing the error A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.
<Router>
<Routes>
<Route exact path="/" element={<About />} />
<Route exact path="/shop" element={<Shop />} />
</Routes>
</Router>
Check if you have installed react-router-dom version 6. for version 6 you must wrap up all 'Route' inside a "Routes".

Browser Router (React app ) on Github not working

i have a little React app project and i have deployed it in Github. It works, even i am using import { BrowserRouter, Link, Switch, Route } from "react-router-dom"; to routing and works ... for my home component but not for the rest. This is my code: `class App extends React.Component {
render() {
return <div>
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Switch>
<Route exact path ="/" component={Show} />
<Route exact path="/contact" component={Contact}/>
</Switch>
</BrowserRouter>
</div>
}
}
export default App;`
I have used this in local machine without the "basename" and worked. Now, in the github server my problem is that it is currently showing my first component when you visit my app main url but is not working for the other component, "/contact". I am not sure if i have to use the '<Link to ' property. Anyway, i just want to know why is working for my main url path (https://namegithub.github.io/main-path/) but not for any other path (https://namegithub.github.io/main-path/contact).
Sorry is a dummy question but actually i am just giving my first steps in React.
Thanks!
you can you this code
import {BrowserRouter as Router,Switch,Route} from 'react-router-dom'
return <div>
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route exact path ="/" component={Show} />
<Route exact path="/contact" component={Contact}/>
</Switch>
</Router>
</div>

React router No Match 404 not working when deployed?

I added a No Match 404 error page to my website, and it works fine when I go to the wrong path on localhost, but after I deploy and go to an invalid path like .../invalidpath I get the default netlify page not found error. Below is my App.js component:
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Navigation from './components/navigation/Navigation';
import Home from './pages/home/Home';
import Projects from './pages/projects/Projects';
import Contact from './pages/contact/Contact';
import NoMatch from './pages/404page/404Page';
import './App.scss';
function App() {
return (
<div className='app'>
<Navigation />
<Switch>
<Route exact path='/' component={Home} />
<Route path='/projects' component={Projects} />
<Route path='/contact' component={Contact} />
<Route path='*' component={NoMatch} />
</Switch>
</div>
);
}
export default App;
If you've built the app with create-react-app and you're deploying to Netlify, you need to add a _redirects file inside the public directory of your project in order to support client side routing (React Router). It should have this inside:
/* /index.html 200
Details here.
Also, check the official docs from Netlify regarding for Redirects and rewrites

React Router mount routes from external package

I am trying to develop an app that takes other "apps" as "plugins". This base app would include only basic auth routes and other apps would define their own routes within them.
How can I accomplish this with React? I suppose React Router could have something, but I have not been able to find it.
I come from a Ruby on Rails world where I could have a gem as an engine and on the base app I would just mount the engine on a given path. I was looking for something similar to that, such that on my base App.js I could simply import ModuleARoutes from 'module-a' and somehow insert it into the base app's <Router> component like:
<Router>
<ModuleARoutes path="/module_a" />
</Router>
Any guidance is much appreciated! Thanks!
UPDATE
Using the answer from #felipe-lanza I had my ModuleA like this:
import React from 'react';
import { Route } from 'react-router';
import { BrowserRouter } from 'react-router-dom';
const Example1 = () => (<div>test 1</div>);
const Example2 = () => (<div>test 2</div>);
const App = () => (
<BrowserRouter>
<div>
<Route exact path="/" component={Example1} />
<Route exact path="/example1" component={Example2} />
</div>
</BrowserRouter>
);
export default App;
export { App as ExampleApp };
And on my base app I have
import MainStore from './stores/MainStore';
import AuthStore from './stores/AuthStore';
import App from './App';
import ExampleApp from '#module-platform/example';
const stores = { MainStore, AuthStore };
const Routes = () => (
<Provider { ...stores }>
<Router>
<Switch>
<Route exact path="/" component={ Login } />
<Route path="/dashboard" component={ App } />
<PrivateRoute path="/example_app" component={ ExampleApp } />
<Route component={ NotFound } />
</Switch>
</Router>
</Provider>
);
And now if I navigate to localhost/example_app I do get the expected result (a div with "test 1"). However, I would expect that navigating to localhost/example_app/example_1 would render the div with "test 2", however it still renders "test 1". As a matter of fact, any location with localhost/example_app (e.g. localhost/example_app/asdfasdfa) will get me the "test 1" div rendered.
What am I doing wrong?
If I understood correctly, wouldn't that be akin to rendering the child apps below the base app as different routes?
I.e. (inside your index.js):
<Router>
<Route path='/' component={BaseApp}/>
<Switch>
<Route path='/child-path-1' component={ChildApp1}/>
<Route path='/child-path-2' component={ChildApp2}/>
<Route path='/child-path-n' component={ChildAppN}/>
</Switch>
</Router>
Then each child app could have its own routes, and so forth.

Resources