DEV Community

Praveen Kumar Saini
Praveen Kumar Saini

Posted on • Originally published at praveen-me.github.io

Implementing Simple SPA Routing Using Vanilla JavaScript

In this article, I am going to implement SPA routing using Vanilla JavaScript.
So, the main motive behind this article to get an understanding of how SPA routing works. Before we get into this we need to understand the main components of routing i.e Web History and Location API.

History and Location Object

Let’s first talk about window.history. History contains all the browser history you can simply access it by typing history and then you’ll get the whole history object and the variety of method’s it has.

window’s history objectwindow’s history object

And another one that we are going to use is window.location. It contains all the information about the current location such as origin, pathname, etc. If you type location in your terminal then you got the whole location object.

window’s location objectwindow’s location object

Let’s start Routing

So, first of all, we need to make an index.html. It contains all the markup for our app. For this right, we just need to make a div of the id *of **root*.

index.htmlindex.html

Now, we are done with that make our page. That is going to render in root area.

Our three different componentsOur three different components

Now, we make our three different pages let’s import them in our index.html’s head **section. Now we have to use a server to serve these pages so in this I am going to use **live-server. If you have live-server it’s well and good just go to the folder directory and run live-server otherwise install it using npm i -g live-server.
Now, it’s time to make our main JavaScript file that contains all our routing logic.
Let's make a file called app.js.
Then first we have to decide our routes and page specific to that particular route and put them in an object.

    const routes = {
      '/' : home,
      '/contact': contact,
      '/about': about
    };

Our next work is to render a page when the index initially loaded. For that first, we have to select the root div and then use innerHTML method to add the content to the element according to the path.

    const rootDiv = document.getElementById('root');
    rootDiv.innerHTML = routes[window.location.pathname];

Here window.location.pathname will give the current path and when the page is loaded the current path is going to ‘/’. But our work is not done here yet. Now, we also have to make the route for ‘/about’ and ‘/contact’ page. For that, we are going to create a simple navigation menu.

Simple navigation for navigating through sections.Simple navigation for navigating through sections.

Now, we are going to make a function that helps us to navigate through section it takes a path and then uses history.pushState() method that takes three parameters i.e state, title, and the route to push and to push the current route into history object so we can also navigate through the browser backward and forward button and then render the section according to the current path.

onNavigate MethodonNavigate Method

Now, just call this **onNavigate **method on the **onClick **event of our navigation menu’s a tag. We just need to do this.

    <a href="#" onclick="onNavigate('/about'); return false;">About</a>
    // repeat for other routes also.

Congrats you just make your own router and when you pressing browser’s forward and backword button you see that the route actually changes but wait for your page is not changing. So, this is because when the browser call’s it’s pushState() method than another method is also called i.e window.onpopstate it’s a simple function where you can customize it according to your need. So, whenever the pushState is called we are going to render our section. For that all we need to apply this.

    window.onpopstate = () => {
      rootDiv.innerHTML = routes[window.location.pathname]
    }

Congrats you finally have done with it.

If you want to follow the code. Check out GitHub repo from here.
If you want to connect with me check out my Twitter and Github.

Discussion (4)

Collapse
sadick profile image
Sadick

Hey Praveen. Nice write up. Just a couple of things.

  • Setting content with innerHTML makes your implementation open to XSS attacks if you plan to add content that is not generated by you. This could be content coming from your users like usernames.
  • Having a screenshot of code (onNavigate) method makes it hard for readers to easily copy and paste the code provided. We like copy pasting a lot 😁
  • Lastly on the naming of the method onNavigate. This gives an impression that the code will be called once the navigation happens. I think something like navigate would have been more appropriate.
Collapse
am_pra_veen profile image
Praveen Kumar Saini Author • Edited on

Hi Sadick,

Thanks for your feedback. 🙂
For your first point, I just want to say that this article is just for demonstration purpose.
Else, I consider your other points and will consider them in my future articles.

Collapse
sadick profile image
Sadick

May what can help is If you are aware there is a security risk in your implementation, you should mention it in the article just to let whoever is reading know about it. I raised it because it wasn't mentioned in the article.

Thread Thread
am_pra_veen profile image
Praveen Kumar Saini Author

I'll edit this article as soon as possible.

Thanks, Sadick for your feedback. 🙂