I use BrowserRouter as React Router Dom, and while I try to access a specific path say http://localhost:3000/recoverPassword, the URL can't be resolved. I can't go for HashRouter as the client is not that impressed to see the # in the URL. I came across the reason and found this is how we able to rectify it using web-pack. But I don't use web-pack in my project. So I wanted to know whether is there any alternative approach without using any module bundlers?
import { BrowserRouter as Router, Route } from "react-router-dom";
class App extends Component {
render() {
return (
<Router>
<div>
<Route exact path="/" component={SignIn} />
<Route exact path="/recoverPassword" component={RecoverPassword} />
</div>
</Router>
);
}
}
Note:
Locally it works with no additional config, but when I deploy to Amazon AWS it couldn't resolve the path.
Update #1
We can configure s3 bucket to resolve the error by pointing the error document also to index.html like this answer explains. The create-react-app hash trick shall do the remaining with BrowserRouter.
But my team had hosted the build to production in EC2, I don't have
the access to it currently, need to have a look at how the same can be
configured out there. Meantime it would be great if someone can share
any info as an answer regarding how to deal this in EC2.
Thanks.
Related
I have built an app that doesnt have a server. It just pulls data from a couple of endpoints.
When someone tries to access a page that isnt the root URL they receive a Page not found message.
I havent managed to find a solution to this that doesnt involve writing a server. Im really hoping that I can avoid that because the app really is too simple to need it.
When I navigate to http://url.com/nextPage it returns a Page not found, but if I navigate there from the root http://url.com/ I dont have any issues.
I have not pushed an app to production before so this was an unexpected issue, but it is also important to how the app works that users are able to access a page directly via the URL.
My App.tsx file. Both pages are just straight forward React.
import { BrowserRouter as Router, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Route
path='/'
exact
component={HomePage}
/>
<Route
path='/nextPage'
component={NextPage}
/>
</Router>
)
}
Since now I know you are using Netlify as your hosting provider, there is a way to do it without having your own server. Netlify has lots of configuration, one of it being redirects.
You could try adding to your Netlify.toml the following:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Or, you could create a _redirects file, with the following content:
/* /index.html
Take a look at this documentation: https://www.netlify.com/blog/2019/01/16/redirect-rules-for-all-how-to-configure-redirects-for-your-static-site/
Since I'm using redirect from react-router-dom to handle my routes in a react app, I'm
Say someone hits:
example.com/privacy-policy
it gets to redirected to:
example.com
and also if someone hits :
example.com/privacy-policy/test'
it is getting redirected to :
example.com'
how to avoid the redirection for example.com/privacy-policy/test' but it should redirect forexample.com/privacy-policy'
The reason for all your routes going to example.com is because create-react-app uses --history-api-fallback option`. See docs.
This option enables History API Fallback support in webpack-dev-server , effectively asking the server to fallback to index. html in the event that a requested resource cannot be found.
So you need to use react-router-dom package and make use of BrowserRouter and Route and Switch components and define your routes.
<Router>
<Switch>
<Route path='/' exact component={ExampleHomePage}></Route>
<Route path='/privacy-policy' exact component={PrivacyPolicy}></Route>
<Route path='/privacy-policy/test' component={PrivacyPolicy}></Route>
</Switch>
</Router>
You can find a lot of examples online. Such as:
React router docs
Another example to get started
I created a ReactJS project with the create-react-app package and that worked well, also I'm starting the application using npm start command.
So the application is landing on http://localhost:3000 by default, but I wanted to configure my landing URL to something like this http://localhost:3000/google where /google will be useful to configure the apache web server to detect my application.
NOTE: There is a way to redirect using react-router-dom to <Redirect from="/" to="/google" /> option and this will work once the application is loaded. But I am expecting my application should be accessible only with this URL http://localhost:3000/google. That means all my webpack, node_modules, public URL should go via /google only.
How to configure the base URL of web application ?
I think you have the answer to your question here: React Start Landing URL
The first one by #Bhojendra Rauniyar
Hope it helps!
If you are using react-router you can use the basename prop to set the sub directory
<BrowserRouter basename='/google'>
<App />
</BrowserRouter>
OR you can redirect / to /content in your Switch block
<Switch>
<Redirect exact from="/" to="/google" />
<Route exact path="/google" component={ContentComponent} />
</Switch>
I have a nested structure where i host the react build as follows level1/level2/level3. When i hit the static hosted build using serve with localhost:3000/level1/level2/level3 it redirects correctly to localhost:3000/level1/level2/level3/title/cat/id. But when i try to hit
localhost:3000/level1/level2/level3/title1/cat1/id1 directly it just returns Not found.
I have the browser router code as follows
<BrowserRouter>
<Switch>
<Route path="/level1/level2/level3/:pageTitle/:category/:id" render={AppBody}/>
<Redirect from="/level1/level2/level3/" to="/level1/level2/level3/title/cat/id"/>
</Switch>
</BrowserRouter>
Why does default redirect work but not when we try to hit the url directly?What's the correct way to fix this?
This works just fine for me, so I think there is some other aspect of your code that is causing a problem.
Here's a code sandbox with a simple index.js that includes your router code:
https://codesandbox.io/s/vmyzkj1lvy
You can use this URL to see the results for the particular URL you mentioned:
https://vmyzkj1lvy.codesandbox.io/level1/level2/level3/title1/cat1/id1
The problem could not be actually the react router but instead your server. So first check that your server is actually returning a response when visiting /level1/level2/level3/title1/cat1/id1.
Your react router is actually changing the url in the browser when it hits <Redirect from="/level1/level2/level3/" to="/level1/level2/level3/title/cat/id"/> without sending a request to the server.
You can use this python gist as a server for static serving for your react app that I believe would solve your problem ;)
This SO thread explains how to bundle a react app for deployment to a specific subdirectory on a web server. I would like to bundle my react app to work on any subdirectory on my webserver. In other words: Is it possible to build a react app, such that I can move it from
http://server/foo
to
http://server/bar
or
http://server/foo/bar
without rebuilding or changing anything?
If you are using react-router-dom, If you know your directory name you could set basename to "/directory-name" in the router
or
If you want to set the base name to be dynamic, use
(Note: This won't be useful if you are using sub routing)
or
Incase of sub routing, set a standard string to your routes
Example:
let basename_path = null;
var url = window.location.pathname.toLowerCase();
if(url.indexOf("react") === -1){ // If string(react) not available
basename_path = "/";
}
else{
var array = url.split("react");
basename_path = array[0]+"react/";
}
<Router basename={basename_path}>
<Route exact path="/react/home" component={home}/>
<Route exact path="/react/contactus" component={contactus}/>
<Route exact path="/react/aboutus" component={aboutus}/>
</Router>
in package.json
"homepage": ".",
Answers to this and similar questions seem to neglect that, if using client-side routing (like React Router) there are some back-end changes that should be made when serving from a subdirectory.
There are several approaches to this. One is to use <HashRouter>; that approach is described well here, or in the React Router docs.
Another approach is to use <BrowserRouter> with Express. Here are the steps for that:
In your app:
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Route path="/your_route">
...
</Route>
<Route exact path="/">
...
</Route>
</BrowserRouter>
Then, in package.json, add:
homepage: "https://example.com/mySubdirectory"
(Note that "." will not work, if you're using client-side routing.)
Then, in Express, try the connect-history-api-fallback package (which is recommended in the Vue Router docs).
const express = require('express');
const historyFallback = require('connect-history-api-fallback');
const app = express();
app.use(historyFallback);
Without this, users will not be able to directly enter https://example.com/mySubdirectory/my_route in the browser's url bar; they'll get a cannot GET error.
You can see an example of the above with Apache here.