Universal React: Yes you should do it!
I recently came across the blog post Universal React: You’re doing it wrong by James K Nelson. His main statement in this article is, that universal react applications are not necessary and you should avoid using the history API and developing a universal application to safe time.
What is a universal react application?
First of all we need to define what a universal react application is. It means that you develop a react application that can do its initial rendering on the server and then runs completely in the browser.
This brings a couple of challenges. First of all we need to create a way to render the application on the server. Thanks to ReactJS this is very easy. The bigger challenge is to pre-load data. Think about a News page that first needs to load all the News from a API. React’s render API on the server is synchronous so we need to build our self a system to first pre-load the data and then render it. While at the same time we need to implement a way so the client loads the data (if the user stumbled onto the news page after the initial server-side rendering).
Another grey area is to be a 100% true universal application you also need to be able to execute business logic on the server (e.g. after submitting a form). But so far I haven’t found any good way to do that and most people when they talk about universal application they just talk about the initial rendering of information.
Is it really more complex?
James’s main point why to avoid universal react application is the added complexity. This is not 100% wrong. But the truth is, if the system is implemented in a simple way, you just have to create the complex part once, follow some conventions (like you have todo with many frameworks) and you don’t ever have to worry much about it during the regular development cycle of your application. For example the convention could be adding a special static method to your router components that load data via promises (take a look how the system in erikras/react-redux-universal-hot-example works).
But do we really need it?
This is a really tricky question. As James correctly said:
Yes, and you’re (probably) not Facebook
I still think there is more to it then just doing it because the big players do it. Even if your site is behind a login screen most of the time. As soon as you have some marketing content on the beginning (and even if it is just one page) you want that to be index. It is true that Google is now able to index single page applications but there are still other search engines out there too. And if you are going to run a successful website you should take care of everyone not just for one player.
So should I use pushState
There is a bit older article called React and pushState: You’re doing it wrong by James K Nelson. In that post he appeals to not use pushState and instead use a hash-based routing approach. It sort of plays into this discussion here because one of his points was that we don’t need server-side rendering.
We already talked about why I think server-side rendering is something that we should implement but there are other reasons for using pushState instead.
- The user is more familiar with paths. Imagine getting an email that says “we haven’t seen you for a while please login to our website to keep your account” with a link that is not a regular path but instead a hashbang url. As a developer we might be ok with that an end consumer might freak that out a little.
- You can still use hash bangs. If you use regular paths for navigation you can still use the hashbang for its original intended use-case. To jump to anchors on the page. You could have a big Dashboard where you have links to different charts. This would not be possible if you have a hash-based navigation in first place.
- It was only a temporary solution. If you do some research on the internet everyone said that the hashbang for routing was just a temporary workaround until there is a History API implemented in all browsers. Since we are lucky enough to have that now there is no longer a reason to use a hash-based navigation.
As I explained before I am a huge believer that a universal react application is possible and the trade-off is way smaller than you might think at the beginning. In addition to that I am not saying that James is wrong in his articles. They have very valid points but in my opinion he missed a few important points that are very relevant to this discussion.
But please let me know what you think? Are Universal apps useful or not very important? Do you develop one/given up developing one? What are the challenges and solutions you faced?