Back to Table of Contents


What CoPilot thinks a cat looks like

By Jesse Pence

Hey there!

Welcome to my client-side manifesto! This first chapter is just a general overview of myself and the project. The second chapter includes a brief history of client-side routing and the concepts behind it before we get our hands dirty.

Click here if you want to jump to the history.

No worries if you want to skip even that and get right to the meat of the project!

Just click here, and we’ll start building.

I started learning Javascript with #100Devs in March, and it has absolutely consumed my life since then. What started as a fickle thought of a new career has fully blossomed into an obsession, and I’m learning more every day. I learned Node and Express over the summer, and I created a few small server-side apps using templating languages like EJS.

But, ever since I started playing with React in August, I have been completely consumed with the differences between client-side and server-side rendering and routing. I felt like I had a good bearing on how classic server routing worked, but that understanding only further bewildered me when I tried to apply it to the client side. I understood the basic idea of a React app on a page, but the fact that it could load different data based on the url without interacting with a server was too much for me to comprehend.

So, in order to gain a better understanding, I decided to do a deep dive on the topic by porting the same app with a few interesting features to several different routers. But, the APIs have gotten so good at this point that much of the work is abstracted away and I didn’t really learn anything about how it all worked. So, I went the extra mile, and I built a client-side router myself. It was hard and I made some mistakes, but I want to share what I learned with the world.

One thing that I want to point out is what this series of articles is not. This is not intended to be a tutorial of best practices. While some of this code may prove to be useful as you determine what routing method to choose for your project, I want to stress that I am very much a beginner. Part of the reason that I have a comments section on this website is because I want to learn from the readers just as much as I want to inform anyone, so feel free to point out my unfortunate errors that are certain to exist throughout this piece.

Also, I know there’s a lot of crazy jargon in this field. I’m only defining what is necessary, but I’ll be attempting to sprinkle the entire piece with links to better resources when I reference obscure topics. If you see this1, you can assume I’m paraphrasing someone who knows better than me, and you can just follow the foot note to know more.

This article is really just a summation of my understanding of a complex topic, but I have spent quite some time working on these projects for the sake of furthering that understanding. I personally had some difficulty tying together all of the disparate resources, but I did manage to find a few that were especially good that I will be highlighting– especially the Remix Router docs page here2 and Ryan Florence’s personal writings here3

I built a small shop app that has a few products that it calls from a fake database hosted right in the public folder. It uses the database to dynamically create individual pages for each item based on the route parameters and the database ID. This is usually the trickiest aspect of routing which usually involves regex, but I wanted to see one way it could be done without it.

So, I included a native asynchronous data loading solution. This seems to be the direction things are leading in the routing world, as almost every library is starting to include something for this. This can be seen as testament to one of the major flaws with React that they are seemingly attempting to fix with the introduction of the Use hook.

The app has a few other features to demonstrate client-side routing. One that you might not expect was a reactive search bar that filters the products on the page based on the URL in the address bar. This helps show how state and routing are intertwined in a client-side app.

Another interesting routing feature I wanted to explore was how to handle 404 errors and redirects. You might think this is a silly aspect to focus on, but it’s actually pretty important. When you really think about it, the amount of things that a user can type into the URL bar is pretty much infinite. So, it’s important to handle 404 errors in an efficient manner.

One can assume that much of this will change over the course of the next few years. React Router apparently shook the community when it switched away from imperative config files to declarative component based routing from v3 to v4. The first React Router version of my app uses this component style, only for my final RR version to use a config object just like v3– although with greatly expanded features.

Like everything else, these things seem to go in cycles of popularity and development, and server-side rendering of JavaScript is rapidly improving. In terms of rendering and routing, the role of the client is changing. Indeed, this distinct separation between the client and the server may become outdated altogether as we move towards a more dynamic web. I’ll talk more about this in the next chapter. I hope that this series of articles will help you understand the current state of the art and help you decide which method is best for your project.

So, join me as I travel through the history of client-side routing.


  1. This is the footnote…

  2. This part of the React Docs is a great resource for understanding the concepts behind client-side routing.

  3. Ryan Florence is a React Router maintainer and has written a lot of great articles on the subject.

Table of Contents Comments Next Page!