My Road to Isomorphic Apps
Tags: react, webdev, story
Published: 2020-01-07 23:03:50

_The web app world changed a lot in the last years_

When I started coding, we were creating the pages in a static way. Maybe you remember that. We created a little app with our HTML, CSS and (if you were little crazy) Javascript. 

## Static Pages

At that moment we only created pages with a simple structure and only reused little things. The scalability of these projects was very heavy. All file work alone, for sample on a simple landing page to one company, we had one HTML by page. At that time, the developers started loving jQuery. Many developers knew jQuery but he didn't know Javascript, that was crazy times.

For sample, if you went to **/about .html**, you received an about page. This page has its own style and JavaScript code. Something similar to that.

![static page example](https://thepracticaldev.s3.amazonaws.com/i/hhyuxg345b23imgxn619.png)

## Server Pages (PHP)
In my experience, I used PHP and his frameworks before to use a Javascript framework. To reuse many parts of one page, we have includes functions on our server. This a sample on PHP but it's the same or similar to other languages and templates, like Java using something like JSP.

![server page php example](https://thepracticaldev.s3.amazonaws.com/i/kmbk150or271t0tfclmh.png)

We came to the **PHP** _frameworks_ like **Laravel**, **Symfony** and others. This way to reused page takes a superpower. On these frameworks, we could create layouts and extends that to only add the content that we need to use it. 

## Single Page Application (SPA)
With BackboneJS comes the idea to SPA, an HTML creates dynamic pages by JavaScript. But the most relevant framework that all developers remember that it starts with the SPA is AngularJS. 
On Angular, you create a simple mapper from route to template, and this template uses a controller with the JavaScript logic.
The concept of SPA is to create a friendly experience to the user with a flow very similar to a desktop application.
This type of apps creates a lot of work on the UI side and creates a boom to JavaScript. So many developers started to learn JavaScript with AngularJS.  And now we have pages created just with javascript.

### Some issues on SPA
The best thing on this type of app is the experience because you don't need to request the page to the server and you could create an animation between a route to route because it is the same HTML page. But not all is great...

- **Not a friendly integration with SEO**
Friendly SEO is very hard, because when you or a bot try to get the code. You received something like that...
![SEO result sample](https://thepracticaldev.s3.amazonaws.com/i/n14zydidvyv2cwqos6f5.png)
Currently, SEO understands those pages but I think that it's not common behavior. If you request a page you wait to that page return structured information about what is it. Which brings me to the next point...

- **It's not normal behavior to the browser**
If you, sometimes, had set up manually an SPA you discovered the 404 issues on AngularJS. If you want to remove the '#' of the URL to simulate the real URL, you need a node server that on all cases send the main HTML file. 
All browsers expect that when the user uses a URL, that loads content. So if browsers received *falsy empty* content, it's so weird.

- **Memory leaks**
Having the same page loaded for a long time can cause considerable problems with your computer memory (browser crash, issues with the power battery, etc) 

- **Tricky browser loading indicators**
If the browser indicator says that the page completes the load, you would be sure that the page is ready. But is not the case to SPA pages.

## Server-Side Rendering (SSR)
With Node appears the possibility to run JavaScript from the server.

So, we could use it to create better web apps. But.. could we run our beautiful UI frameworks form the server? Yep, we can.

### Only Server Side
If you want to render React from the server you have to use react-dom/server with a utils function, renderToString. Check this sample:

![only server-side example](https://thepracticaldev.s3.amazonaws.com/i/xqranf5qb6lsism7217f.png)

Easy right? Well, not. 

This is only the first part, if you need to handle an event or change the DOM, this doesn't work. The function name says all that you need to know, this creates a string with the HTML and sends the initial view to the client, despite using React this app is not reactive.

### Server Side World
If you want to be this App reactive, you need to use **hydrate** React function. Instead of using render, that creates a DOM, you should use hydrate, that matches a DOM with VDOM on React. 

For more information, you could check on React [documentation](https://reactjs.org/docs/react-dom.html#hydrate). 

All **SSR** frameworks use a similar behavior. For sample on [this](https://github.com/zeit/next.js/blob/cffa2e3f2165b58b77fb354d3f74a4ac8222b68f/packages/next/client/index.js#L246) code lines on [Next](https://nextjs.org/)

![hydrate example](https://thepracticaldev.s3.amazonaws.com/i/pu4epfgyw134qw9fmyi8.png)

### Isomorphic Apps
With all this knowledge on your head, let me explain what is isomorphic apps. If we see the app wrapper on a SPA we should see something like that:

![isomorphic apps](https://thepracticaldev.s3.amazonaws.com/i/onu5a8iwqaw5mprir19s.png)

We only change the common render function by a hydrate function. This code will run on the client.  We create a little server with the following code...

![server side configuration](https://thepracticaldev.s3.amazonaws.com/i/vif90zxjhifoemgbehfs.png)

In this case, the app will render on first time by the location that the server received on the request. This creates an isomorphic router, the first rendering populates the request URL as a router URL. But when the app is loaded,  the route is managed by the client.


### The Future
![state propagation from server to client](https://thepracticaldev.s3.amazonaws.com/i/bzj3vrmx8eqf8mk9a72r.png)

When you need to propagate the state from the server to the client. You could implement something like the image.

In these cases and others, re-hydration has a considerable cost. Because we need to propagate the data from all the VDOM. 

Some people propose some solutions to solve these issues. 

These ideas are about reducing the scope to hydrate the app. We could hydrate by events or only hydrate the visible part on the browser, like lazy-hydration ([check that GitHub repo](https://github.com/hadeeb/react-lazy-hydration)).


**That's all folks, thanks for reading.**