I'm a bit confusing how routing works with react-router.
Normally when a request comes to the server for a request like:
http://www.example.com/path/to/file
A request will make it to the server for that file, and then the framework will handle the request.
With react router, how does this work? Do things somehow get intercepted at the client side (browser) and then only a request to index.html will be made to the actual web server?
I'm assuming somehow the request to /path/to/file gets trapped by javascript and only a request to index.html makes it to the server, but how does it do this?
React router is a client side router, so when we do configs for nginx or any webserver in general with react router we specify and send only 1 file known as index.html and then the JavaScript code provided by react router figures out which component to serve by looking at the path and history of the browser.
So no matter which path you request it's indirectly index.html which gets the request but with a different path which then figures out what to do.
One part of the answer is looking at the basename prop of the Router. Everything that comes after that is handled at client side as the location corresponding to the app current state.
Another part of the answer is that when using BroswerRouter (as opposed to a HashRouter that uses the # separator in the URL before the local app state), the server has to serve the app "index.html" for any route that does not correspond to an actual static ressource or an API route. This is usually treated as the fallback behaviour of the server.
When using BrowserRouter, if your server base url is http://example.com/app, and your current app state is /user/12, that makes the current browser url http://example.com/app/user/12. If you refresh your browser, it will make a request to http://example.com/app/user/12 and your server app has to answer with the index.html of the app. When loaded, react router will interpret the current state as /user/12, following the configured basename.
When using a HashRouter, with the same server base url and app state, the current browser url would be http://example.com/app/#/user/12 and when refreshing the page, the browser would make a request to http://example.com/app/
Related
We created a react js application.
Problem: Not able to hit react URL from the postman to run component's function.
local URL: http://localhost:3000/rules/routine
Note: Above URL can be reached without login.
When we are calling a url from browser it's working however when we hit from a postman then it always returns public/index.html page but not the expected response.
So it is not calling the proper url http://localhost:3000/rules/routine.
Please find attached screenshots on below links
browser hit: https://prnt.sc/73gDWh4PiHgu
Postman hit: https://prnt.sc/fhVL78yaiATP
It's technically possible, and working it seems, but I suspect your expectations are a little skewed in what you think Postman will do or is capable of.
Keep in mind that all React apps are effectively a single page app, even when they use a routing/navigation package like react-router. react-router is only manipulating the URL in the address bar in the browser window, the app is still running from the single location on a server where it's hosted, i.e. public/index.html.
The servers hosting the app are configured to route all page requests, i.e. "http://localhost:3000/rules/routine" to the root index file, i.e. "http://localhost:3000/index.html" so the React app is loaded and can handle the "/rules/routine" internally.
So from what I see here, the response from Postman is absolutely correct and what I'd expect to see. It made a request to the development server for a nested directory "/rules/routing" and the server responded with the root index.html file. When the browser makes this request to the development server and gets a HTML file back it loads and renders it, and in this case, it's your React app.
Postman isn't a browser so it's not going to load the HTML response and do anything with it.
I have a React App using React Router Dom, I have been trying to figure out how to get client-side routing working, if I load the web app normally everything works fine, and I can access different components at different URLs using react-router-dom.
But if I refresh or try and access the url to a routed component directly, the server returns 404 not found as its making a request not to my SPA but the server.
I was wondering how in a .net 6.0 Web api, how to route anything not beginning with /api to my SPA.
Thanks!
After lots of trial and error, adding
app.MapControllerRoute(
name: "api",
pattern: "/api/{controller=Home}/{id?}");
app.MapFallbackToFile("/index.html");
to Program.cs, I was able to have the fallback url map back to index.html
So I have a backend running in expressjs and I have multiple routes on it. Now I just followed this tutorial to set up a RESTful api on express. Now I want to switch to full react on the frontend, so that I will have an api running in the backend to get things from the database and am thinking using fetch from react to get that data. I saw many people say that is the best way to do it. But now there is an issue, I am not sure how to route for this. I have react-router setup so I am assuming I would use that. But how can I serve these files to the client side? How can I make sure every route except /api routes just serve my js files? Like I have a built folder already with an index.html and main<hash>.js. I am running them easily but how can I intergrate them with express? I was not able to find any answers to this. How can I route for a reactjs app to be served using expressjs? and also I saw a tutorial telling me to use a * route but that means even my api routes will only point to that.
There are three ways basically to render an application.
One is Server Side Rendering, the other one is Client Side rendering and the third one is Isomorphic rendering.
So if you are defining your routes in Nodejs and navigating the application through those routes than it will be entirely server side rendering.
I saw a tutorial telling me to use a * route but that means even my
api routes will only point to that. ? How can I make sure every route
except /api routes just serve my js files?
Regarding this what you can do is
server.get('/api', (req, res, next) => {
//You can handle the request here
})
server.get('*', (req, res, next) => {
//You can handle the request here
})
You can define your route in this order.So by this way any call to the '/api' will be handled by the first route and all the other request will be handled by the second route.
Now I want to switch to full react on the frontend, so that I will
have an api running in the backend to get things from the database and
am thinking using fetch from react to get that data
Here you dont need this.It will be an client side rendering completely
server.get('*', (req, res, next) => {
//You can handle the request here
})
For this you can create an react app from scratch or use some boilerplate (https://github.com/facebookincubator/create-react-app).
There you can define all the routing and simply call the url http://localhost/api/xxxx and get the data and you can use this data in the frontend.In this case there will be a Nodejs Server which will be serving the frontend and the expressjs server will he hosting the 'api' service to get data from.
I have react-router setup so I am assuming I would use that. But how
can I serve these files to the client side?`
How can I route for a reactjs app to be served using expressjs?
The Reactjs app when compiled is a combination of static files comprising mainly of html, css, javascript. If you want your app to be served by your express.js server then you need to use isomorphic rendering. It is by far the best approach for rendering application as it is good for SEO and initial fast page load. It comes at the cost of a complicated setup. In this case, whenever the page refreshes or the first request comes, express will serve the first page (index.html) and index.html will contain the required static(bundled) js and css files for client side rendering. The first rendering will be done by the express server and the subsequent rendering will be done by browser itself.
I have a backend using express to serve a static directory, to the path /, in which is contained a single page frontend. This backend also serves an API REST.
The frontend is built in React, and uses react-router to route the user from the different views of the web application.
If my react-router have two entries, let say /app and /config,
how can I redirect the client to that view of the application, if the user enters directly the URL in the web browser's address bar?
Right now, if I do that, Express gets the request and obviously returns a 404 message, as the single page is served to / path.
A simple way to resolve that is to always (even on 404s) send to user the index.html in your express route handlers.
See: https://stackoverflow.com/a/25499007/2624575
However, you need to take care of some things:
1) Your React Router code should start to handle 404s: https://stackoverflow.com/a/37491381/2624575
2) You need to handle correctly the path to your assets (icons, css, js, etc), otherwise you'll send the same index.html to those kind of resources (which will make your page render incorrectly)
3) Make sure that react-router is using browserHistory (the history that doesn't use hashes #), This way React will be able to render your routes correctly
Hope it helps!
Recently I am using MERN stack as my web development stack. However, I could not figure out that how to handle client side rendering and server side rendering.
I have a URL like: http://localhost:3000/addItem and I route this URL using react router. It works well. But when I input the URL in the browser and hit the enter button, 404 paged showed.
I understand the reason is I did not set up the get request in express.js
However, my question is should I just leave it in this way? or I should also implement the get request in express as well?
In your index.html file you might have included the js bundle in the script tag file like below.
src="js/bundle.min.js"
It should be
src="/js/bundle.min.js"
You need the '/' to make it absolute path. else it'll try to find the JS file in the relative path of the URL you entered.