Introducing & Installing Solid Router
so my friends we've learned some of the building blocks are solid now, how to make components, how to use props, signals, how to attach event handlers, etc. But at the moment, our site is still just one page which shows the app component content. Now typically websites have more than one page, unless they're one of those pages that just scrolls down for Infinity, probably tries to say something at the bottom. But generally, we want to make more than one page, right?
And the way that we make more pages with solid is to use something called the solid router, which is a separate package that we need to install. So over here, we've got the solid router GitHub page, and I'll leave this link down below in the video. Now if you scroll down a little bit, you're going to see how to install this package right here. So we want to copy this command and then head back to our project so we can install it.
So open up a terminal, cancel out of the dev server process if you haven't already by pressing Ctrl and C, and then just paste in this command. And just remember to get rid of this little angle bracket at the start as well, otherwise, you might get an error when you press enter. So press enter. That's going to install the router package for us so that we can start implementing different routes and pages in the website.
How Front-End Routing Works
And it's important to note as well that these pages and routes are purely going to be front-end pages and routes. We won't ever be sending requests to the server for different HTML pages. Whenever we go to a different route, if we click a link in the site, the way front-end routers work is that all of the routing is handled in a browser.
So imagine we click on a link to go to a different route in the site, for example, to forward slash about. Then what the solid router will do is look at that route and say, okay, well for that route, I'm going to swap the current component in the page for the about component. And the HTML page is still the same HTML page, we're just swapping out the content inside it depending on the route that we visit. I hope that makes sense. And that's pretty much the way any front-end router works, whether it be Solid, React, Vue, or something else.
Anyway, if we go back to the docs, we can see we need to do a couple of things. First, we need to wrap this router component which is imported from the solid router package around the root app component. And we do that so we can use the router anywhere inside this app component or child components within the app component. And then we can set up our different routes like this inside the app component. And you can see that each route registers a component to show in the page when we visit that route. Okay, so let's try setting this up in our application.
Implementing the Router and First Route
So I'm going to go back to our project and then open up the index.jsx file where we render this app component and we need to place the router component around that. If you click on this, it should auto import from solid.js, which it has done. So make sure that surrounds the app component meaning we can use the router and routes anywhere now inside what's inside this component. So anywhere in the app component or nested components.
So let's save that and head back to the app component. Now, where do we want to output our routes or our page content? Well, let's think about it. We want this header to appear on every page. We want the image, the banner at the top to appear on every page. So they don't go inside the routes. But down here, this is actually a page content. So what I'm going to do is place the routes right about here. And in here we can have our different route components. Okay, one for each page.
Now we need to make sure that these are imported from solid.js. So what I'm going to do is go back over here and copy this thing, this import. So we import routes and route from the SolidJS router. We'll do that up here. So now what we could do is make a couple of different routes for different paths. So for example, I could say the path of this route is just forward slash, and for that we want to show some kind of home page component. So we could say the components to show here would be equal to the home component. Now we don't actually have that component, so
Creating the Home Page Component
let's go ahead and make it. And what I do is whenever we have page components, I place them inside a Pages folder just to keep things organized. I'm going to call this home.jsx. And then I will create a new function and we'll export it as well. So export default and then function and that function is going to be called home.
Inside here, all we want to do is output some content for the home page. Now, the content I want to output for the home page is this stuff right here, this grid of cards. So I'm going to copy that, or rather cut it, and paste it inside a return statement right here. So this is the template we're returning for the home page. Now, in order for this to work, we need to import the card component inside this file because we use the card. So let's come up here. We don't need it inside the app component anymore because we don't use it there. And let's instead paste that at the top of this file.
So now we have a home page component. We can register it down here by saying home. I'm going to click on this to auto import it. And it's imported it right here from the pages folder, which is cool. So now what we're saying is, okay, when we go to forward slash, so the root path of the website, I want you to show the home component. And that's going to get rendered right here inside this routes component. So when we go to the home page, we're still going to show all this at the top, and then when we go to the root component, or rather the root route, it's going to show the home component right here. So if I save this, everything so far should be pretty much the same because
Adding a Cart Page Route
all we're doing is moving... oops, we need to make sure we're running the dev server. so npm run dev.
But then when this runs everything should be the same. We do get an error. Okay, so that's because inside the pages folder, we're trying to import the card and it has to come outside of the pages folder first of all, so double dot then into the components. Okay, so now everything is working the same way because we still have this card component, all this stuff, it's just that it's being rendered as the home page right here in the same place essentially. But now what we can do is create further routes. So for example, I could create another route which would be forward slash cart. And when we go to forward slash cart, I want to render some kind of cart component or cart page. So let's do that as well, cart.jsx. Inside here, we want to export a default function called cart.
Building and Debugging the Cart Page
And inside this we need to return a template. Now, I'm just going to copy this from my repo, so we don't have to type it out instead. Simple. So all we're doing is having a div, we give it a max width class which is medium, a margin in the y direction of strength a, and then margin in the X direction of auto. And then we have a card. It's rounded, and inside that, just an H2 which says, "Your shopping cart."
Now, in order to do this, we have to import the card component up here. So import the card from dot dot forward slash to come out of the Pages folder, then into components, then the card. All right, so now we have that component. We can go ahead and register it right here, card. I'm going to click on that to import it at the top so it works. And now my friends, let me get rid of that space. If we go over here, we have to manually go to forward slash cart. Not card, sorry, forward slash cart. And then we get this card thing right here.
Now at the minute, that doesn't seem to be showing the title. And I've just figured this out, it's because I've stupidly inside the app component, don't know why I've done this. I've said I want to show the card component for when we go to forward slash cart. Instead, I want to show the cart component. so click on that to import it up here instead. All right, save this and now my friends, we should see that card with the title inside it. Awesome.
So we go to the home page, we get the home page content. If we go to the cart page, we get the cart page content.
Now, at the minute to go to these pages, we have to manually type out the address up here. It would be nicer if we could have some links up here in the nav bar so we can just click on those to go to the different pages instead. Because at the minute, when I'm going to the addresses manually, I'm actually sending a full request to the server to get that HTML page back, to start the whole application again, and to put the right content in. Same for if I go to forward slash cart right here. No matter what the route is, I'm clicking enter, so sending that request to the browser, or rather the server, to send back an index.html page to the browser.
So what I'd like to do is place some links up here instead. When we click on those, the Solid framework is going to intercept those requests, and it's just going to swap out the content instead. So let me go back over here, and we want to output some links inside the header. Okay, and they're going to come after the H1. So let me paste in a couple of anchor tags. So the first one to forward slash and the second one to forward slash cart. So let's save this and take a look. And if we go to the home page, yeah, we see the home page. Cart, we see the cart page. So that's working.
However, this is not the behavior that we want, because when we're using these anchor tags, what's happening is every time we click on one of these links, it's sending a fresh request to the server for the HTML page again. That's the behavior of anchor tags. And I can show you that if we inspect over here, and then go to the Network tab. And what I'll do is just make this a little bit smaller. I'm going to clear this, but watch when I go to the carts page, we're going to see a new HTML page over here. So if I scroll up a little bit, you can see we get a new document here, so the HTML page, right. I'm going to clear this again and then if I go back home, then again when we go up, we're going to see that we get an HTML page. All right, so this is not the behavior we want.
What we'd like to do is tell Solid, look, this is a link whereby I want you to intercept the request and I want you to just swap out the components in the page right here when we go to different routes. And we do that by using a special link component called A.
Using the Link Component for SPA Navigation
that we get from solid.js router. So we just import that and then instead of a small a, we use that capital A component right here and down here. And now this will work the way we want it to. So I'm just going to refresh and then if we inspect again, go to the Network tab. Okay so now watch when I click on cart, then we don't get that extra download from the server. And that's because we're not now requesting all of that extra content from the server. We are just telling solid to say okay well when we go to forward slash cart I will look at that request, intercept it and then swap out the content for the cart page content because that's what we said right here. So it looks at this looks at the component it needs to load in and it does that.
Okay, so that's pretty much it for the solid router at the minute. There is more to the solid router and we'll certainly be exploring different features as we go forward. But for now this puts us in a good place so we can have different pages. In the next lesson, what I'd like to do is show you how we can fetch data from somewhere and then take that data and inject it into a template. So what we'll do is we'll fetch some product data and we'll cycle through that product data and output a card for each product that's coming in the next lesson.