server-side react-router without being isomorphic - reactjs

In my web app, I don't want to use hash-based routing, I don't want to see any # appear in my URLs. I want to use RESTful URLs, e.g., http://www.example.com/blog/id.
react-router can deal with client-side routing quite well, but if a user hit enter on the browser address bar or refresh the page, the request will be sent to the web server and then the web server has to understand the URL and handle the routing.
Isomorphic is a good solution to this situation since it can render any page on both client-side and server-side. Actually there are many react starter kit projects on Github which claim to be isomorphic.
In my opinion, isomorphic looks beautiful but it's too expensive to write code: you need to make you react components render successfully both on client-side and server-side, which needs developers to make great efforts.
So here is my question, can I just make the react-router be isomorphic, not the entire code?

Yes. You can use react-router for a purely front-end (non-ismorphic) app with HTML5 history.
The routing is determined client side, so react-router will spit out the expected page.
However, whilst you don't need to write any server side code, you will need to configure the web server to point your routes to the correct place. This usually means pointing every single request - or every single valid request - to the same HTML file or entry point. Exactly how you do this depends on what you're using to serve your pages - Express, Apache etc.
I hope that makes sense.

Related

How is server-side rendering compatible with single-page applications?

My problem is that I'm unable to understand how server-side rendering single-page application frameworks like Next.js receive prerendered, full HTML on the front end without having to rewrite the entire page. For example, the nextjs website states the following:
By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.
Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)
I understand how this bolsters the responsiveness of an SPA on first page load. But after that first load, what makes server-side rendering compatible with SPAs? I think this arises from a fundamental misunderstanding that I can't catch, so here are some further questions I have that might help you to catch it:
Do SSR SPAs always respond with full prerendered HTML, or only for first page loads?
If the former is true, then on subsequent responses, how does the client efficiently render only the difference rather than rewriting the whole page?
Otherwise, if the latter is true, then how does an SSR SPA backend tell when it's responding to a first request, when the response should be the whole HTML, versus a subsequent request, when the bulk of the page is already there and all that needs to be sent is some relatively minimal information?
What am I misunderstanding about what makes SSR compatible with SPAs?
Many thanks in advance to everyone who tackles this question!
Welcome to Stackoverflow :)
Usually SSR is used for initial rendering of the page, so for the first question - for the first page load
This is necessary, so the SPA will be more SEO-compatible (there also might be some performance improvements with this, but it's usually secondary goal) and Search Engine bots will be able to parse pages without the need for JS
The SSR usually has several important steps:
Server render
Sending of rendered data to browser
Hydration. Hydration - is a ReactJS (since we're talking about next.js here) 'function' that binds the server-rendered HTML to the React on the Frontend. So basically binds server-rendered DOM to virtualDOM
After the hydration step you basically have a fully-functional normal SPA, which has it's own routing and able to fetch data on itself.
Usually you have different endpoint on the BE to fetch the data and to render the page. So basically the rendering process on the BE is somewhat similar to what you have on the FE - your application backend fetches the data from separate endpoints, applies all of the logic and renders the app.
Btw, to ensure that SSR works properly, there is a principle called 'Isomorphic code' - i.e. if you're using a library for data fetching, it has to support both node.js and browser APIs. That's why, for example, you'd have to use Next.js own Router when you have a Next.js application - it just works on both FE and BE unlike react-router, which would require some additional steps to achieve that

Deep Linking in React without React-Native or React-Navigation

I have a request from a client to implement deep linking in our React application whereby clicking a link will take them directly into the installed app (potentially to a certain point but not sure on that yet).
To my understanding react-native and react-navigation both handle this as part of a feature set within "Linking" that they offer. However it seems excessive to import a framework just for deep linking (perhaps not though).
After googling I can only really find references to deep linking on react-native or react-navigation.
What is my best course of action?
Let's get to some basics first, then it will be clear.
In modern SPA's, say with React, it's common for the SPA to handle navigation itself. You need to use browser's history API. It's because your SPA is just a single index.html with bunch of js code, so it sort of virtual, every page is constructed by your app. In order to not reinvent a wheel, its easier to use some library for that, say react-router-dom.
But then everything works as expected, and you have deployed your app. When user wants to get some deep page, say, https://my-awesome-app.com/deep/page/1, browser will just send a request to a server, asking: "Please, server, give me a page 1.html, in folder page, in folder deep". But server doesn't have that file, because it has literally one index.html, because its a SPA application. Then we need to tell the server to re-write all deep routes to index html, here is an example for my app hosted on Netlify:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
When user will ask for that page, server will 'redirect' that request to the index.html and my react-router-dom will figure out which 'PageComponent' to render based on that path.
So, you can implement routing in your app yourself, probably using browser's History API, but I guess it might be easier to use library. But it's your call.
On the other hand if your app is not an SPA, the story might be different, because say in NextJS routing is implemented in framework itself, and if used deep linking would require different setup depending on how app is deployed.
Deep-linking is handled largely by Apple and Google server-side
https://www.adjust.com/blog/dive-into-deeplinking/
React-native provides extended functionality for deep-linking within mobile apps but normal web-applications there is no need to implement it there. Use universal links or Google specific links as standard linking within your web app to enable deep linking

Can I use ReactJS or Angular to create multi-page web applications?

I am a little bit confused about front end frameworks. I read that if you used ng-route or react-router it would make your app a single page application, so does it mean if I don't use ng-route/react-router and instead used express for server rendering would the app still considered a SPA ?
To answer your final question, if you're serving bits of your site from different Express routes, then by the definition of a Single Page Application it's not a SPA anymore, no.
However, there's nothing explicitly wrong with doing that. ReactJs is a tool and a way of working with components. If you want to work with components, but you're more comfortable with serving your individual views from different server-side routes then just do that. Not everything needs to be a SPA. Once you're comfortable with the core of how React works from a mark-up/component point of view, you can start incorporating partial page renders and client-side routing etc.
I think you are not getting the point about SPA. Please read the following:
https://en.wikipedia.org/wiki/Single-page_application

MVC Routing vs Angular Routing: Is not enough with just MVC Routing?

As far as I know the hash symbol(#) is the key when implementing routing in Angular. The web server only takes care about the part of the URL which is before the hash, and Angular takes care of the rest.
I´ve read some articles that explain how to remove the hash from URL. But if I remove the hash(#) from URL: Which routing works first?
OK, it is MVC. In that case we have to edit the MVC Route in order the server to understand the URL. But we are at the beginning again. Does it make any sense to use Angular Routing and MVC together ? Is not enough with MVC Routing?
Maybe I´m missing something. I hope you can help me.
Does it make any sense to use Angular Routing and MVC together ? Is
not enough with MVC Routing?
TL;DR;
I've rarely use both. The only time I use both is when I need to authenticate the user for some routes.
Long answer
1. Authentication
As you already figured out, Angular routing is great when you want to navigate to another page without the roundtrip to the server. It's usually a SPA. But there might be a scenario when you need to authenticate the user before sending the HTML, then MVC routing will be handy. I wrote an answer about it here. Note the difference between sending HTML and sending DATA to to the client. If you have no server routes the html-pages (or templates) will be fully accessible (unless you limit access in web.config or some other way). Some times the HTML-pages can contain some sensitive information as well...
The most common scenario is if you have a public site with an admin-part. But in my experience you can handle this on client side with client-side-routing only. It's usually the data that is sensitive, not the templates.
2. Server-side logging
The other scenario is when you want to do some logging on server side. For example if you want to log every page request. This can often be done on the client as well... Look at Google Analytics. But you might want to log the request even if the browser has javascript turned off.
3. SEO
There might be some SEO-issues when using client-side-routing. But this is only when we render the html with client side templates and if we compare to completely rendered views with MVC.Net. Do not confuse me posting the link with me actually agreeing with the content...
4. WCAG
In my country all government sites need to follow WCAG. One of the rules are - no javascript. Or at least that the site should be fully accessible without javascript. Without javascript client-side-routes are simply very difficult. ;)
These are some examples when you might need both server-side and client-side routes. But to sum up, in most cases client-side is enough.

Why to create Angular routes if you already defined Express routes?

I'm new in MEAN stack area and I have some doubts related to Angular routes. Why should I recreate on the client side the routes already made in backend with express.js, what are the benefits? Is this the only way how Angular.js works? I saw some examples with Jade.js and it wasn’t necessary to recreate the routes on the client side, making the things simpler.
Thanks!
Disclaimer: I haven't specifically used Angular myself, but I have used Backbone.js for the same purpose, and the same arguments apply.
There are many use cases where it makes sense to define routes on the client side, not the server side. For instance, I do a lot of work with Phonegap using Backbone, and the architecture is generally a REST API for the back end, and the data gets used to render the pages on the client side. This approach has the advantage that it reduces the amount of data sent over the network, generally making the app quicker. Client-side routing also preserves browser history when compared to just updating the existing content via AJAX.
Ultimately, it's something you have to consider on a case-by-case basis. For something that's very dynamic, building it as a single page web app with client-side routing may make sense. For a more traditional web app, such as a blog or ecommerce site, you're probably better off defining routes on the server side.

Resources