 So at this point, we have built what you can actually call a blog. We have design. We are respectful of the user's bandwidth. We load pretty fast. It's looking pretty good. But something that gives a little bit more cohesion is some polish, some showbiz, if you will. And so I thought what we could do is we could build a router that does nice transitions from, for example, the overview page to one of the individual blog posts and back. And this router that I wrote is actually a single self-contained JavaScript class. So let's figure out how that's going to work. As I said, the router is a standalone JavaScript class. It isn't really tied to anything except click events. So the first thing the router does is add a click event listener on the document level. And once a click happens, it checks if A, the click is on a link tag, and B, if that link links to one of our own documents. And if both of these conditions are true, that's where the router actually starts doing something. It checks if the document that that link tag links to is a document, and if a document is one of our own. And if that's the case, we're going to fetch that content, use push state to change the URL in the address bar, and then pass the content on to an animator that will fade out the current content on the page and then switch it out with a new one and fade it in, giving a really smooth and nice transition for the user so that they know what is actually going on. So this approach has a couple of advantages. On the one hand, we are what I call hijacking link tags. So that means that link tags are still going to work as they should, even if JavaScript is disabled or a router code for some reason throws or just doesn't load, so that means that links are still going to work. They might not have a transition, but the user will end up where they wanted to end up. The other advantage is that link tags emit click events, even if the event was actually a tap on a touchscreen or even someone pressing the Enter key if, for example, they are using a screen reader. This is very important because this means that our transitions become a progressive enhancement and that all our content stays accessible. The router's constructor adds a couple of event listeners, one for clicks and one for pop state. The one for clicks, as I just explained, is for the link tags and the one for pop state is to react to the user pushing the back button in the browser. It basically triggers the same logic. It just grabs the target URL from a different spot. The router also loads a spinner and the spinner is supposed to be shown when loading the next view takes longer than 50 milliseconds to show the user that something is in fact going on. It's just taking a while. Note, however, that I'm loading the spinner dynamically. If I loaded it statically, it would have to complete loading the spinner and still my router could even start running. And that's a bit backwards because the spinner is only ever needed once a click happened. So really, the router should run first before the spinner is being downloaded. And that's exactly what dynamic import helps you solve. The navigates function responsibility is to download the next view and transition it into view. It makes heavy use of async await because I think it's a really nice pattern to start an animation and await until it's done. And then you can start the next animation so you have a really nice and imperative way of dealing with these kinds of animations. If you want to know more about async and await, I did a micro-tip on that a while ago. So we're going to link to that in the description. And in the next commit log, we are going to talk about the message bus, which is something that I implemented. And it turned out to actually make loading even more efficient, and it made my life easier. And I found it really interesting. So if you want to watch that, you should subscribe. And I'll see you next time.