Go to main content
August 4, 2021
Cover image

When working with Single Page Application, it’s important to know how works the history and location objects to do routing. Then in a next article we will implement a routing library in React, react-router like.

The browser history is the list of all visited pages. It allows us to navigate through the history of our tab by going back to previous visited page or forward to the next visited page.

You can access to the history object thanks to the window with window.history.

The properties and methods exposed by the History API are the following ones:

history.length returns the number of pages that you have visited for the current tab.

It defines the behavior after a reload of the current page. There is 2 values possible:

  • auto: if the user has scrolled, then after reloading the page, the page will automatically scroll where the user was before.
  • manual: after reloading the current page, the user will be at the top of the page wherever the user was on the page before.

An history state is a sort of context in which you can store any values (that can be serialized) that needs to be kept when going to the next page. Each page has its own state.

history.state returns the state for the current page you are. This value cannot be changed.

This method allows you to push an entry in the history. It takes as parameters:

  • state: the state for the new entry
  • title: You can pass a string if you want to define a title for the new state. Note that, nowadays, this parameter is not used by browsers
  • url: this parameter is optional, it defines the new entry url if you want to change it. You can path a relative or absolute path until you stay on the same origin. This new url will not be loaded by your browser.
Example: pushState

If we have:

/*
| History stack |
| ------------- |
| Page 3 | << We are currently on this page
| Page 2 |
| Page 1 |
*/

After executing:

history.pushState(null, null, 'Page 4');

We got:

/*
| History stack |
| ------------- |
| Page 4 | << We are now on this page
| Page 3 |
| Page 2 |
| Page 1 |
*/

This method allows you to replace to current entry in the history. It takes the same parameter as pushState:

  • state: the state that will replace the current one
  • title: you can pass a string if you want to define a title for the new state. Note that, nowadays, this parameter is not used by browsers
  • url: this parameter is optional, it defines the new entry url if you want to change it. You can path a relative or absolute path until you stay on the same origin. This new url will not be loaded by your browser.
Example: replaceState

If we have:

/*
| History stack |
| ------------- |
| Page 3 | << We are currently on this page
| Page 2 |
| Page 1 |
*/

After executing:

history.replaceState(null, null, 'Page 4');

We got:

/*
| History stack |
| ------------- |
| Page 4 | << We are now on this page
| Page 2 |
| Page 1 |
*/

history.back() will move you to the previous page in the history.

Example: back

If we have:

/*
| History stack |
| ------------- |
| Page 3 | << We are currently on this page
| Page 2 |
| Page 1 |
*/

After executing:

history.back();

We got:

/*
| History stack |
| ------------- |
| Page 3 |
| Page 2 | << We are now on this page
| Page 1 |
*/

history.forward() will move you to the next page in the history.

Example: forward

If we have:

/*
| History stack |
| ------------- |
| Page 3 |
| Page 2 | << We are currently on this page
| Page 1 |
*/

After executing:

history.forward();

We got:

/*
| History stack |
| ------------- |
| Page 3 | << We are now on this page
| Page 2 |
| Page 1 |
*/

history.go([integer]) allows you to move in the history further than 1 step backward or forward, depending on the integer passed as parameter:

  • none or 0: it will reload the current page
  • < 0: it will move backward in the history (-1 will do the same thing as history.back())
  • 0: it will move forward in the history (1 will do the same thing as history.forward())

Example: go

If we have:

/*
| History stack |
| ------------- |
| Page 3 | << We are currently on this page
| Page 2 |
| Page 1 |
*/

After executing:

history.go(-2);

We got:

/*
| History stack |
| ------------- |
| Page 3 |
| Page 2 |
| Page 1 | << We are now on this page
*/

Now that we have seen what can be done with the History API, let’s focused on the Location API.

The Location API allows us to get some information about the current URL of the page we are on thanks to the window.location or document.location objects.

The properties and methods exposed by the Location API are the following ones:

window.location.href returns the full URL.

In my example it will be: https://romaintrotard.com:443/en/posts/prevent-react-rerendering?searchKey=searchvalue#when-does-a-component-render.

window.location.protocol returns the protocol scheme of the url (http: or https:).

In my example: https:.

window.location.hostname returns the domain of the url.

In my example: romaintrotard.com.

window.location.port returns the port number of the url.

In my example: 443.

window.location.host returns the concatenation of the hostname + : + port.

In my example: romaintrotard.com:443.

window.location.origin returns the concatenation of protocol with host.

In my example: https://romaintrotard.com:443.

window.location.hash returns the anchor part (also named fragment) of the url (after the #, # included).

In my example: #when-does-a-component-render.

window.location.search returns the query string part of the url (after the ?, ? included).

In my example: ?searchKey=searchvalue.

window.location.pathname returns the path of the url. It’s the part after the origin part, starting by a /, without the anchor and query string.

In my example: /en/posts/prevent-react-rerendering.

window.location.reload() is a method that refresh the current page.

window.location.replace(newUrl) is a method that redirects to the newUrl (the document is loaded, contrary to history.replaceState). It will replace the entry in the history stack.

Example: replace

If we have:

/*
| History stack |
| ------------- |
| Page 3 | << We are currently on this page
| Page 2 |
| Page 1 |
*/

After executing:

location.replace('Page 4');

We got:

/*
| History stack |
| ------------- |
| Page 4 | << We are now on this page
| Page 2 |
| Page 1 |
*/

window.location.assign(newUrl) is a method that redirects to the new url. But, contrary to window.location.replace it will add a new entry in the history stack.

Example: assign

If we have:

/*
| History stack |
| ------------- |
| Page 3 | << We are currently on this page
| Page 2 |
| Page 1 |
*/

After executing:

location.assign('Page 4');

We got:

/*
| History stack |
| ------------- |
| Page 4 | << We are now on this page
| Page 3 |
| Page 2 |
| Page 1 |
*/

I hope I didn’t lost you in the explanations. The parts that are important to know for my next article about “how to make a react-router like library” are the methods replaceState, pushState and go of history. These methods allows us to make some navigation in a single page application (without reloading the document). And pathname, search, hash of the location object. It’s from this values we can know where we are to show the right routes :)


You can find me on Twitter if you want to comment this post or just contact me. Feel free to buy me a coffee if you like the content and encourage me.