Check out a free preview of the full Astro for Fast Website Development course
The "Dynamic Routing" Lesson is part of the full, Astro for Fast Website Development course featured in this preview video. Here's what you'd learn in this lesson:
Jason showcases the process of generating dynamic routes within Astro's file-based routing system. Astro page files can generate multiple pages that match specific criteria by incorporating dynamic route parameters directly into the filename.
Transcript from the "Dynamic Routing" Lesson
[00:00:00]
>> Let's make this bigger again, and we're going to create a new file. And this time it's gonna live inside of a directory. So it's gonna be in the blog directory. And then to determine or to make something parameterized we can use square brackets. And I'm just gonna grab anything and turn it into .astro.
[00:00:20]
So the file name is [...slug].astro. And that is the the dynamic path segment. So we are gonna visit this at /blog/ whatever the thing is. And that gets us to the frontmatter. So we're gonna start in here, we're going to, again, import that getCollection out of astro.
[00:00:50]
And then we're gonna import our layout again. And I probably could have copy pasted this part but that's all right. So this time we are a little bit deeper. So we're gonna go up two levels and get the page. Then, we're gonna export an async function. And that async function is going to be called getStaticPaths.
[00:01:14]
And what we need to return from getStaticPaths is an array. And that array includes objects with params. And the params would be they need to match this, so we would need a slug and that's gonna need to be something. And we're also gonna send back props which are optional.
[00:01:37]
But that is an object if we do decide to send it. So our job here is to get the blog posts and turn them into an array of these objects that have the params and props that we need. So up at the top of getStaticPaths, we're going to grab our blog posts again in the same way that we did on the blog homepage.
[00:01:59]
Grab that blog, okay? And then here, instead of just hard coding an array, we're gonna blogPosts.map and get the post. And we're gonna return from each one, our params and our props. And I'm gonna get rid of this part so that it stops yelling at me. So our params are gonna be an object and our props are gonna be an object.
[00:02:26]
And inside of our params we want the slug so we can get the post.data.slug. And for the props, I can just pass through the whole post. So now I don't need to individually load each post because I already loaded the whole list. So I can just pass it on down and then have it available as a prop already when I'm starting to work with the code itself.
[00:02:53]
And that means that right here, and this is the only part that gets a little bit confusing if you've never seen this before. Because we're exporting this, that means that the props are available. So right here I can use that post out of Astro.props. So this is being fed into Astro.props and I have it here.
[00:03:15]
So then I can get the content, because the only thing I don't get out of the frontmatter is the actual page content. And the way that Astro handles that is they give us the post and a render method, which will give us the ability to render this out.
[00:03:34]
I'm not gonna worry about the fact that this is typed as any. If you want to, you can import some special types that will set the props to be the content collection posts and then you'll get the autocomplete and stuff. I'm not super worried about it. I'm close enough to this one that I don't care.
[00:03:56]
I would probably change it otherwise. And I also just realized that I made an error. The slug is part of the frontmatter but it's a special part of Astro. So it's slug is post.slug, it gets hoisted outside of the data. Because that is a specific piece that is added for a lot of reasons that are outside of frontmatter, we need it for different functional things.
[00:04:20]
So they give that right at the top level. So now that we've got that, we can start building out our layout. So as usual, we wrap the whole thing with a layout. Let's get the post.data.title. And then underneath that, in fact, I'm just gonna copy paste this part out.
[00:04:49]
This time section here, cuz it's exactly the same. So we can drop that in here. And then I want to show the content. And I'm not worrying too much about the overall formatting here. I'm not showing the post author. I'm not gonna add a lot of additional markup here.
[00:05:08]
That's not really the goal of what we're after. I just wanna show how you would get one of these displayed on page. And if we reload, a-oh, we got pages. And if I head back, hit one of these. And there it goes, and if we add another one, that'll show up as well.
[00:05:30]
So it is very straightforward. And what I like about it is that it brings in familiar things. This getStaticPaths is pretty well-worn territory at this point. Most of the frameworks that have a static export option do give this general API. So it's something that you've potentially used before if you've built with modern front end frameworks.
[00:05:56]
And it gives you all the power that you need to do quite a bit here. And again, we could do a lot more, right? We could pre-process this object. We could make an additional call out to a third party. We could try to find related posts. We could do a bunch of stuff.
[00:06:09]
Do keep in mind though, one of the things that gets a little tricky as you start building these things out is that this is executed at build time. So typically what you wanna do is you wanna minimize the number of API calls that you're making. So something like getting the entire blog collection is good.
[00:06:27]
Because it's one call, you load all the data, and then you can loop over that data and do things. If you have hundreds of thousands of posts, maybe it's not as good, right? And then you might wanna do something like just get the first hundred, and then use dynamic rendering to get the older posts that don't get as much traffic, right?
[00:06:42]
So there are some strategies that you wanna keep in mind as you're using something that builds statically by default. That in a dynamic environment, you can just ignore. But you pay the price by having to maintain your servers. If you wanna do it on a static build, you can ignore it, but it'll get slow.
[00:07:01]
And so as you start to get to really high numbers of things, or really slow queries, like if you're doing a really intense query to go through multiple layers of your API and figure out related posts, or similarity rankings, or something that takes a lot of computer processing, you might wanna start thinking about how exactly does that get done?
[00:07:22]
And how are you caching those calls if the data doesn't change, and so on and so forth, so that your builds stay fast. Because one of the major assets here is because Astro is built the way that it's built, it's powered by Vite, the builds are very, very fast, a second or less out of the box.
[00:07:39]
And that means that if we don't add things to make it slow, we will be able to publish something to production in a few seconds. And that's really really powerful, right? So you don't wanna break that as you start getting into more and more complex builds, question?
>> You don't have to go into this if it's gonna be too long, but is there any sort of ISR capabilities for Astro if you wanted to do it that way?
[00:08:03]
>> Yes, but not built in the way it is in Next. So-
>> Just put it behind a CDN.
>> Yeah, what you would is you would wanna say, put Astro into hybrid mode or server mode so that the pages themselves are making a request. And then you would use a cached API call with a timeout on it.
[00:08:21]
It's not like Astro doesn't have a TTL built into it where you can just say, I want this page to render once every five minutes. But building that with Netlify, for example, you can just set a cache expiry on the API. It's hitting and it'll get the same general outcome.
[00:08:39]
But yeah, not built in. Probably the biggest thing is the content is a little bit different. This is something that what we're effectively doing here is we're saying take this markdown file and render the content of the markdown into an astro component. And then we use that Astro component in the contents of the file.
[00:09:01]
So the the functional outcome is it just takes the Markdown and turns it into HTML. But it's important to note that this is not HTML, this is an Astro component. And that's gonna be important when we talk about the RSS later.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops