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.
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'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/
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!
My current setup is as follows:
Starting the server and going to localhost takes me to home.ejs as stated here (in my front end routing):
However, when I go to localhost:3000/posts, the posts template is infact not being injected into my index file (where my ui-view is). Ive been following the mean stack guide from thinkster, but have been making a few changes (not using inline templates)
My question is, how do I setup my routing such that localhost:3000/posts will actually take me to the posts page?
You are dealing with two types of routing, client side and server side. Client side is located in your app.config function in your angular code. That function should be calling html files, which are located in your public directory. These files are not rendered server side via express and they wouldn't not be able to read the ejs format.
Typically with MEAN stack applications, you just render your index file when the user logs in, and from there the Angular router takes over with html files and you handle your routing from there. If you don't want Angular routing, you have to set up your index.js file to render pages as they are called with res.render('posts')
You can change your posts.ejs file into an html file, and just call it via Angular when the user navigates to localhost/#/posts (depending on your version and configuration of Angular).
Your Express server side routing will handle your API calls as you have defined in index.js. In order to call those APIs, you will make GET or POST requests via Angular's $http method, through a service or factory.
Hope that helps, if not, let me know and I can elaborate or provide examples.
To solve this, I used Eric Hartmanns solution. By changing posts.ejs to posts.html, and letting the angular router take over on client side, the page was being rendered. However, when typing in localhost:3000/posts in the address bar, the page wasnt being rendered and the server was being hit for some reason. To get around that I simply made a new get route in express and re-rendered index whenever that route was hit like so:
router.get('/', function(req, res) {
res.render('index');
});
I'm getting really frustrated with configuring the Routing on our app, which is using sailsJS and angularJS.
The problem is, that the browser doesn't know about angular, so any request like /login returns a 404 Error from sails. I need a solution, to keep the sails routes from the angular ones,
One solution would be to disable html5Mode, but i really don't like the look of URLs with the /#/ which is typical for angular.
I have researched a lot on this and haven't yet found a good answer or maybe a working project for this.
Is what I am trying to do even possible right now?
If you're using HTML5 mode with Angular, then you need to configure your web server (in this case SailsJS) to respond with your index.html file for requests to /login or any arbitrary routes.
If you navigate directly to http://localhost:3000/login in your web browser (assuming you're running Sails on localhost:3000), Sails needs to respond with your index.html so that your Angular app can bootstrap and then display the appropriate route. Then, subsequent links that the user clicks on in your app will be intercepted directly by the Angular router instead of Sails directly.
Angular has documentation about making HTML5 mode work correctly here.
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows Angular to differentiate between the part of the url that is the application base and the path that should be handeled by the application.