How does Single Page Applications (SPA) navigate?

Tram Ho


A single-page application (SPA) is a website that re- renders content when navigating (for example, when a user makes a click on a link), it will not make a request to the server to get the whole thing. new html set for that SPA page too.

Although there are actually many ways to deploy SPA applications, most of them are built on browser mechanisms and APIs to build core functions. is the core to understanding the working principle of a single-page app.

SPA classification

A SPA can manage the state based on an external source (eg, url address) or itself has its own state management mechanism.

Comparing the two types together, an SPA using the second method (internal state) has a limitation: you only access that SPA from a fixed address ( root of that SPA page), during the user process ( user ) makes navigation ( navigate ), there is no way to show that navigation outside of the browser .

This will lead to restrictions, such as the one the user wants to share your spa for someone, then surely they will copy the link url and send it to friends they want to share (share), while recipients share it will also only be accessible from the root , and you will be the one explaining how to access the content you need to share .

With the first approach, location based SPA , you can share the link for a specific user and make sure when the user accesses the link (assuming that user has full access to the link or If the link is public to all users, then the content displayed will correspond to the link they receive, because this time the url ( url ) always corresponds to the user’s navigating process.

-> Therefore, this article will focus on state management mechanism based on location .

Location Primer

When the url is something that the user sees and interact with, SPA will work with the window.location function, which allows us to extract and work with each part of the url without having to manually parse .

For SPA, there are 3 parts in the url that are important: pathname , hash , and search (also called query string), while hostname and protocol are temporarily ignored.

pathname is the most important of the 3 parts in the url because it determines what content will be rendered . The search and hash will be used to display additional data .

  • For example, for an address like /images?of=mountains , pathname is /images will be specified that the rendered page is page / images , while ?of=mountains will specify what content will be displayed. on that page / images .

Route matching

SPA depend on the router, the router is a set list of routes, each route will correspond to one location it is match together.

A route can only be fixed to /about or have dynamic elements like /album/:id with an id that any user can pass.

For example :

During the user navigate navigate in SPA , the location will be compared to find the corresponding route (usually just need to compare the pathname of the location ), After finding the corresponding route , the router will re- render the SPA content. for users.

The rendering has many ways:

  • One of them is to model the Observer pattern , the dev will give the router a function that will re- render the SPA and the router will perform a call to this function .

In-App navigation

When the user clicks on a link, usually it’s an <a> tag, usually browsers have default behavior to attach to an event to perform the navigation , when you want to override the browser behavior . they can use event.preventDefault() of JavsaSript, and virtually the SPA are supporting framework for this.

And when the default behavior of the browser is overwritten, the loaction is no longer changed, instead the navigate process will be defined by us and perform the control itself.

How does the browser handle location?

Each browser tab has something called the browser context , which is the browser context that manages a session history – essentially an array of location entries .

An entry will contain information about a location : the url of the location , the Document corresponding to the location , the state that has been serialized , as well as a few other attributes. Each entry has an associated index that specifies its order in the session history array. The browser context also holds information about the current entry being used.


When the browser executes the navigation , a request is sent to the server and the browser uses the received response to create a Document object . This object describes the page (the DOM tree of the page …) and the methods to interact with it. For example, the window.document function is the function to interact with the Document of the current location entry .

Session history

When the user clicks on the link and navigate , the browser tab will build in addition to the session history . Each navigate will make a request to the server and create a new entry (including a Document ).

When the user presses the Back button on the browser , the browser will use the current entry to identify the new entry ( current.index -1 ). Document of the previous entry will be reloaded into the browser .

Now, when users click on a url, the entry is located behind the current entry (the page before back on) will be deleted and replaced by the new entry.

In case of any users navigate to the correct page the current (new location has the same pathname, search and hash to the current location), the current entry will also be replaced by a new entry, but will not affect the other entries .

Above is the mechanism of action of navigation, but implementation navigate without having to request to the server.

How does SPA accomplish this?

History API

Initially, SPA operates on the mechanism that we can change the hash of the location and the browser will create a new location entry without sending a request to the server , later a whole History API for the purpose of supporting development. SPA .

Instead of having to instantiate a document , for each location , the History API will reuse the current document , only update it to match the new location .

History Api has 3 main functions : pushState() , replaceState() and go() . These 3 functions (and the rest of History API ) and can be called via window.history .

Note: Support issues – all current browsers support History Api .

pushState () and replaceState ()

Both the pushState() and replaceState() have the same arguments :

  • The first argument is state : the default argument can be null , this argument is the state of SPA .
  • The second argument is title
  • The third argument is path – this is the address we want to navigate to. This may be a full url , or just a relative path , but it must always belong to the current application (the common protocol and hostname), otherwise, the browser will throw DOMExeption error.

The pushState() function will add an entry to the session history after the current entry . If there is an entry that is behind the current entry , it will be replaced by the new entry , this mechanism is the same as the normal mechanism of clicking the <a> tag as I mentioned above.

The replaceState() function will replace the new entry with the current entry in the session history . Other entries are not affected. This mechanism is similar to the normal mechanism of clicking the <a> tag as I mentioned above, but replaceState() differs in that it can replace the current entry with any locaction .

go ()

The go() function is a way to simulate the back and foward buttons of the browser .

The go() function accepts only one argument : The number of entries to remove from the history . A positive number is equivalent to the foward action, a negative number is equivalent to back , a 0 will be equivalent to a page reload .

In addition, there are two functions history.back() and history.foward() , which will be equivalent to history.go(-1) and history.go(1) .


An entry in the property of the state, 2 function pushState() and replaceState() in argument containing state. So what is state ?

state is data associated with an entry . It fixes navigation – meaning that when you add a state to an entry , navigate away, then return to the previous entry , the state will remain there. The state will be attached to the entry using the pushState() and replaceState() , and can be retrieved with history.state .

Some restrictions on state :

  • The state must be serialized first.
  • The state has a size limit (for example, Firefox has a maximum of 640kb).
  • When we navigate directly to a url , the state will be set by default to be null , so if we set the SPA page logic to depend on the state to render , we will have a problem when the user accesses directly from that url ,

So the state is more useful when using it to store data regardless of the rendering .

Navigate in SPA using the History API

As mentioned above, we can use a click handler – which overrides the browser default mechanism with event.preventDefault() . That handler can call pushState() and replaceState() to perform navigation without pinging the server . However, the History API only updates the session history , so the handler also needs to interact with the router to let the router know the new location .

There are many ways to handle a handler like this. If you use frameworks like Vue or React , you can write something like this:

History API usage makes control easier navigate SPA. However, we still have to handle one more case: when the user clicks on the back and foward buttons of the browser .

Processed with 2 back and foward buttons

When the back and foward buttons are clicked (as well as when history.go() is called), the browser makes a popstate call. To capture this event, we must add an event listener .

The session history will be updated as soon as the above event is called, now we need to notify the router that the current location has changed.

Navigate by changing directly on the url bar

If the user changes the url by editing directly on the url bar, this will create a new Document . The History API now only prevents reloading entries with the same Document – that is, calling history.go() or clicking the forward / back buttons after this will completely reload the page .


This article, along yourself and you learn SPA does the rendering of content, making the navigate how fundamentally, every contribution you can comment below.

I have references at the posts /

Thank you !!

Share the news now

Source : Viblo