Single Page Applications in Cloud Storage

We’ve already written about how our Cloud Storage can be used as a platform for hosting static sites. Today, we’re going to discuss how our cloud can be used to host Single Page Applications (SPA).

SPA as an Approach

SPA stands for single page application. Strictly speaking, it’s a single page website which dynamically updates in a client’s browser. A more general understanding of an SPA (sometimes referred to as SPI, or single page interface) is a comprehensive approach to web development, which is fast gaining popularity today. So what does this approach involve and why is it becoming so popular?

Let’s start with a general overview. Today, the most widespread kind of sites are dynamic. These are sites that are generated on the server side. Despite how convenient this is for developers (each request creates a new page from a clean slate), these sites can sometimes be a real headache for clients. Inconveniences clients may encounter include:

  • Even though some frameworks let you return a form with data previously entered by the client, pages may have to be reloaded to be validated.
  • Generating pages on the server side generates major workloads.

The usual solution to the aforementioned problems still involves generating the site on the server side, but also executing JavaScripts on the client’s side. Scripts can be used to perform actions like validating a form before it is sent to the server. At first glance, this may seem like a feasible solution, but it has its drawbacks:

  • If frontend and backend functions used to be clearly divided (the backend taking care of view generation and logic, and the frontend the display), then the logic will be cloned on the frontend, which is hardly a practical architecture.
  • The code responsible for view generation must be constantly cloned, which causes problems: copypasta, divergences in markup, broken selectors, difficulties maintaining code, etc.

These are problems we can live with of course, but the SPA approach is much more effective in most cases.

With this approach, a site is understood not as a set of different pages, but a set of conditions for one HTML page. When the conditions change, new content is downloaded asynchronously without reloading the page.

An SPA isn’t a site in the traditional sense, but an application running on the client-side browser. This is why from the user’s point of view there are hardly any problems with speed, even when the Internet connection is slow or unstable (like when viewing a page from a mobile device). Since the server doesn’t send the client markup text, but data (mainly in JSON format) and only a small amount of it, sites can load faster.

Lately, there has been a surge in the number of solutions and services that make creating and using single page applications much simpler. We’ll be taking a detailed look at at a few of these.

BAAS (Backend as a Service)

The technology allowing you to draw an interface on the client’s side and to interact with the server by only sending requests (and without reloading a page) has been around for quite a while. For example, the XMLHttpRequest API appeared in 2000. This technology was fraught with difficulties though: the backend authorizing requests and access to data needed to be rewritten.

Everything has since become much simpler thanks to the numerous BaaS services that have popped up. BaaS stands for Backend as a Service. BaaS services give web-app developers a ready-made server infrastructure (often located in the cloud). This saves you time (and usually money) from having to write server code and lets you concentrate on improving the actual application and developing its functions. Using BaaS, you can connect a backend with any function set to an application or site—the appropriate library just needs to be added to the page.

We can look at mLab, which lets you connect a MongoDB database to web applications and sites, as an example.

Another interesting example is FireBase. This service is a cloud database and API for real-time applications. More specifically, this lets us organize data transfers between the client and server in real time: you just add a JavaScript library to your page and configure the data exchange events. With FireBase, a chat or activity stream can be easily implemented.

BaaS services that deserve a look include:

  • Backendless — a ready-made cloud server infrastructure for all kinds of applications. It can be used to add functions to sites like user management, save user data, instant messaging, mailing lists, geolocalization, file management, and more
  • Syncano — an API for real-time applications, functions similar to Firebase
  • QuickBlox — an intriguing product made by Russian developers

Our Cloud Storage can also be used as an external backend for integrating file management functions into web apps and sites.

To use our storage as an external backend, there are two important factors: authentication and content. An authentication key (token) can be obtained by sending a request to auth.selcdn.ru.

The key will have to be set as the X-Auth-Token header value for all data requests. Responses to these requests will include the Access-Control-Allow-Origin header with the value “*”, which gives it the ability to access the cloud from any external domain.

HTML5 History API

Every page on a dynamic site has its own URL. An SPA is built so that a page’s contents can change while the URL stays the same. This could cause problems though: the user may not be able to save a link to a section of a page and come back to it later. There are a few solutions to this problem, though.

Firstly, we could use a hash-fragment (the part of a link that comes after the # symbol). A page’s “virtual” address is placed in the hash fragment, which can then restore previously loaded content. If the user refreshes a page, then a JavaScript will read the hash value, load the necessary data, and display the corresponding section. This option is used in many sites, but it’s worth noting that these URLs (like http://example.com/base/#!/section1/page2) don’t look very authentic. Moreover, they’re made up of two elements: the “real” address, which the page requests from the web server, and the “virtual” address, which defines the logical section.

Secondly, we could use HTML5 History API. History API lets you change a page’s URL within the framework of the present domain without reloading it. For browsers that support this API, there is no difference between the URL that loads the page and the URL given in JavaScript.

History API function calls are also connected to a browser’s Forward and Back buttons and history: when pressing Back, the browser fires a popstate event, which can be processed in JavaScript and display the previous section. For a working example of this, check here.

For a site to use this URL system, the web server needs to be properly configured. It’s imperative that the main SPA page, which is usually index.html, is returned instead of a nonexistent page. In this case, the client’s browser will load the JavaScript which has already drawn the site’s necessary files based on the present address.

This is written in nginx configurations as:

location / { rewrite .* /index.html; }

If the SPA is located on a service like GitHub Pages or our Cloud Storage, then the configuration needs to be set in the control panel.

Search Engine Optimization

Search engines that index single page applications present an altogether different problem. If a site is generated entirely on the client side, then it will be poorly indexed; however, we have seen some improvement in this area: bots have slowly been starting to run JavaScripts while they index.

One way to solve this problem is by generating page snapshots specially for bots. There are various ways to generate pages depending on whether or not they use HTML5 History API.

If hash fragments are used, Google offers a solution: use “#!” instead of “#” to separate the “real” sections of an address from the “virtual” ones. After seeing links with these sections, bots will use the “_escaped_fragment_” query parameter in the URL and insert the part of the address that comes after the hash.

A web server should process these queries in a special way and return full HTML pages so they can be indexed by bots (this is required since the part of the URL after the “#” is not a standard part of an HTTP query). A special meta tag (see above links) is also recommended since several pages may not contain links with “#!”.

If full URLs are used for addressing, then making a site indexable becomes even easier: the corresponding address just needs to be generated on the server. The bot, having visited the site, receives a page with this content and successfully indexes it.

If the site is opened in a browser, then the page will firstly be displayed according to the HTML markup, then the JavaScript will take over; the page will not reload when navigating between links. This can be implemented by intercepting link click events and nullifying their native behavior. In this case, the bot is redirected according to the link (the “href” attribute), and we can control all transfers, processing events as we need to.

We’ll also note that this approach lets us optimize how quickly a site is loaded: modern browsers draw HTML from a server much faster than they load JavaScripts, parse them, and then draw the page in the DOM.

How can we generate an HTML page with only JavaScript code and working directly in a DOM? There are a few ways this can be done.

Firstly, we can install PhantomJS (a so called “headless” browsers built on WebKit, installed via API) and configure it to generate page snapshots.

Secondly, we can use the prerender tool or Prerenderer.io service, which is also based on PhantomJS.

Thirdly, this function is already implemented in several modern frameworks (like DerbyJS and React; another example is react-server-example).

SPA Hosting

There are a lot of platforms for hosting SPAs on the net today. We’ll look at a few of the more popular options.

Dropbox

The most basic option is to host an SPA in Dropbox. To do this, an SPA catalog needs to be created in a public Dropbox catalog and all the necessary files need to be added to it. Then we choose our index.html and open the context menu by right-clicking it. In the menu, we choose “Dropbox → Share Link”. Afterwards, a link will be created that can be copied to the address bar for accessing the SPA.
Lately, attempts have been made to expand Dropbox’s hosting capabilities. However, the biggest problem has yet to be resolved: Dropbox has pretty serious limits on traffic from public links (up to fully blocking them). That’s why this option may only be recommended for showing an SPA to friends and colleagues.

GitHub Pages

GitHub Pages is a free platform for hosting static sites and SPAs. To host an SPA from GitHub Pages, you need to create a repository for it on GitHub and place the static files in the gh-pages branch for Project Pages or in the master branch for User/Organization Pages. All of the changes you make will need to be committed to this repository. More detailed information is available in the official documentation.

BitBalloon

BitBalloon is relatively young compared these other options, but is still a popular option. Every registered user is given 10 MB of disk space for free. To host an SPA, all you have to do is upload the necessary files to the service. BitBalloon automatically minifies JS, HTML, and CSS files, and also connects to a CDN.

A premium account costs $5 a month. Platinum account owners have access to extra features, like mapping your own domains and connecting to various kinds of external services.

Selectel Storage

Our Cloud Storage is a convenient platform for hosting SPAs. Overall, the procedure for hosting a single page application hardly differs from the procedure for hosting static sites, which we’ve written about in our knowledge base. It involves the following steps:

  1. Creating a public container and assigning it a domain: see our knowledge base for detailed instructions.
  2. Setting up special pages: we recently improved the setup procedure. We’ve added another configuration option for processing nonexistent pages (“404 error”). Now you can set a file to be displayed if a nonexistent page is requested, as well as specify the response code (200, 307, or 404), in which case the user will not be redirected to another URL:

This lets you use a full URL.

Other obvious advantages our storage has over other platforms (including those listed above) include our low cost and flexible payment system. We also offer a CDN and flexible container and folder settings.

Conclusion

In this article, we discussed another aspect of using our cloud storage as a platform for hosting single page sites. We hope you found it informative. If you already use our storage for hosting SPAs, please share your experience and impressions. We will of course take all of your remarks into consideration for future developments.