DEV Community

Cover image for Let's explore javascript's Location and History API
Romain Trotard
Romain Trotard

Posted on • Updated on • Originally published at romaintrotard.com

Let's explore javascript's Location and History API

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 History API

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:

length

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

scrollRestoration

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.

state

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.

pushState

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 |
*/

replaceState

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 |
*/

back

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 |
*/

forward

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 |
*/

go

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
*/

The Location API

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:

Note: In the examples bellow, we are going to imagine we are on the page: https://romaintrotard.com:443/en/posts/prevent-react-rerendering?searchKey=searchvalue#when-does-a-component-render.

href

window.location.href returns the full URL.

Note: If you set its value (or the value of location), it will navigate to the given URL, and load the document (contrary to history.pushState or history.replaceState).

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

protocol

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

Note: The colon is included

In my example: https:.

hostname

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

In my example: romaintrotard.com.

port

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

In my example: 443.

host

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

In my example: romaintrotard.com:443.

origin

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

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

hash

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

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

search

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

In my example: ?searchKey=searchvalue.

pathname

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.

reload()

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

replace()

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 |
*/

assign()

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.

Note: If you wonder the difference with location.href navigation is some security checks that assign does you can find on the specification.

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 |
*/

Conclusion

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 :)


Want to see more ? Follow me on Twitter or go to my Website. 🐼

Top comments (2)

Collapse
 
alirezace profile image
Alireza

Thanks for nice examples.

Collapse
 
romaintrotard profile image
Romain Trotard

Thank you for your kind message :)