Astro Crash Course #10 - Dynamic Routes

Net Ninja| 00:08:03|Apr 13, 2026
Chapters5
Introduce the need for a details page for each book and outline making a dynamic route based on the book ID.

Net Ninja shows how to build dynamic book detail pages in Astro using getStaticPaths and a markdown-powered content render.

Summary

Net Ninja walks through turning a list of books into individual detail pages in Astro. The lesson introduces a dynamic route for books using a file named with square-bracket IDs, and demonstrates how to tell Astro which pages to generate via a getStaticPaths function. He explains importing getCollections to fetch all books, mapping them to route params, and passing each book as a prop into the page component. The tutorial then covers rendering the markdown content stored in each book’s front matter by using Astro’s content render helper. By the end, clicking a book link no longer results in a 404, and the page shows the book title and, later, the full markdown content. Net Ninja also confirms how IDs are derived from file names and how the content component renders headings, paragraphs, and lists with proper HTML and IDs. This is a practical approach for static sites where content lives in markdown files and routing must scale to a collection.

Key Takeaways

  • Create dynamic routes with square brackets in the file name (e.g., [id].astro) to make the book ID part of the path under /books.
  • Use export function getStaticPaths() to return an array of objects, each with params { id } and props { book }, enabling Astro to build a page for every book.
  • Fetch all books with getCollections('books') and map them into the static paths array, one entry per book.
  • Pass the entire book object as a prop to the page component so templates can access book.title, book.author, etc.
  • Render markdown content by destructuring Office content from the front matter (content) and invoking render(content) from 'astro-content' to produce HTML.
  • Wrap content in a base layout and display dynamic data, like the book title, before rendering the full markdown body.

Who Is This For?

Essential viewing for developers using Astro with markdown-driven content who want scalable, static detail pages for a collection of items (books, reviews, posts). It covers routing, data fetching, and markdown rendering in one cohesive workflow.

Notable Quotes

"What we need to do then is make a details page for the books and tell Astro to build one of those details pages for each book in the collection."
Intro to creating a dynamic details page for each book.
"The first thing we want to do is get all the books using the get collection function just like we did in the books page."
Fetching the full books collection to generate pages.
"We need to return an array of objects where each object represents a static page that we want to generate using this component."
Defining the structure for getStaticPaths return value.
"And inside this object we need those two properties I keep mentioning. Params to let Astro know the route writers in this page and in that case it's just going to be the ID parameter."
Mapping route params for dynamic IDs.
"We can add the content component instead and now all of the book's markdown content is going to be rendered right here in different HTML tags."
Rendering markdown content via Astro content component.

Questions This Video Answers

  • How do I create dynamic routes in Astro for a collection of items like books?
  • What is getStaticPaths in Astro and how do I use it with getCollections?
  • How can I render markdown content stored in front matter inside an Astro page?
AstroAstro ContentDynamic RoutesGetStaticPathsgetCollectionsMarkdown ContentFront MatterNet NinjaBooks demo
Full Transcript
Okay, so in the previous lesson we updated the books content collections use markdown files instead of JSON and we output the books on this books page in the same way. We also updated the link on each book so that it points to the path books and then whatever the ID of that book is based on its file name. But at the moment if we click on these links we get a 404 page because none of those pages exist. What we need to do then is make a details page for the books and tell Astro to build one of those details pages for each book in the collection. So let's start that process now. The first thing we need to do is make the details page component inside the books folder. Now remember the name of the file dictates the route path and we need the route path to be books and then whatever the ID of the book is. So that second part of the route is dynamic, right? It changes based on the book that we're viewing. So to make a page with a dynamic part of the route we just put square brackets around the file name. For example, I'm going to make a new file called square bracket open ID then square bracket closed dot Astro. And because the ID has square brackets around it we're saying that part is dynamic. So then because that part of the path is dynamic we need to tell Astro exactly what paths to generate using this component so that pages can be built for each one of them. Doesn't know automatically about all of our different reviews, does it? So the way we do that is by using a function with a special name inside the components front matter. So let's add some front matter first of all and inside it we can export that function by typing export function and then the function name needs to be called get static paths. And it's inside this function that we need to return an array of objects where each object represents a static page that we want to generate using this component. And in each of those objects in the array we need to tell Astro two things. The parameter value in the route path, so the ID in this case, and also any prop that we want to pass into the page component when it's built. So we want to build a page for each book in the books collection, right? And so in the returned array we need an object for each book in the collection and inside each object we need to specify the ID parameter, the route path, as well as the book that we want to pass into the page as a prop because we'll need that book in the template. So let's do this. The first thing we want to do is get all the books using the get collection function just like we did in the books page. And we want to do this so that we can make an object for each book, right? So we'll need to make this function async to begin with. And then inside that function I'm going to say const books is equal to await. And then we'll use the get collections which we need to import and then as an argument in that function call we pass in the collection name which is just books. So we have an array of books right now. And in that array is an object for each book. And remember we also need to return an array of objects where each object represents a page that we want to build. And we want to build a page for each of these books. So the array we return is going to be the same length as this array. All we need to do then is map this books array into a new array which we can then return. And that new array of objects will have the params property for each of the objects and also the props property on each of the objects. So I'll say down here return books dot map and then invoke this. And then we'll fire a function that returns a value for each book in the array. And in that function we get access to the individual book that we're currently iterating. So then now we need to return a new object for each book for this new mapped array. So let's do that by saying down here return and then return that object. Now inside this object we need those two properties I keep mentioning. Params to let Astro know the route writers in this page and in that case it's just going to be the ID parameter. So we can add the params property and the value of that should be an object where we list all the different route path parameters. In our case we have the ID parameter since that's what we called the file, right? And the value of that route parameter should be the ID of the book which is the file name, remember? So we can add the ID property and set that to be book dot ID. Next we need the props property to tell Astro what prop to pass into this page when it builds it. So let's add that in next and the value again is going to be an object where we can just add book value as a prop. And that's all we need to do. We're now telling Astro to build a page for each book in the collection and for each book the ID part of the route should be the book's ID and the prop for the page content should be the book entry itself. So then now we can go ahead and make up this page component like any other we already have done. To do that we'll grab the book prop which we said we wanted passing into the page in the function that we just made and we do that the same way as always by destructuring it from Astro.props. After that we can go ahead and use the come down here and first of all add the base layout component to wrap the rest of the page and you want to make sure that gets imported as well. And then inside that layout we'll do a div element with the class of content so it gets styled the same as any other pages. And then finally we're just going to do an h2 tag for now where we can output the book title by using curly braces and then just output that book title inside of it using that book prop. So then let's save this now and see if it works. All right, so moment of truth. I'm going to click on this right here and we go to books Assassin's Apprentice and now we see the title right here. We no longer get that 404. So it's built a page for this book review. If I click on the others they all should work as well. Yep. And this one down here. Cool. And finally this one. Yep. Awesome. So they all work. Okay, so we could now start outputting all of the different properties on the book like the author, the rating and so forth. But if you remember we actually have a lot of content after the front matter in each of the markdown files and that's the content I really want to show on this page. So how do we access that content then? Well, whenever we have markdown content we can get Astro to render all of that content into a special content component. The way we do that is by coming back up to the front matter and saying const then curly braces then content with a capital C because this is a component that we're going to destructure and then we set that equal to await and then a function called render which needs to be imported from the Astro content module. Then all we have to do is invoke the function and pass in the content entry that we want the content from which is the book prop. And now that returns this content component containing all of that markdown content and we can just output that component down in the template. So instead of this h2 here I can just use the content component instead and now all of the book's markdown content is going to be rendered right here in different HTML tags. All right, and now if we click on one of these pages we can see all of that markdown content. And where we had hashes for headings we should get h tags if we inspect these then we can see we get an h3 right here, paragraph tags, hrs, a ul where we had a list in the markdown and so forth. And also it gives IDs to these things as well. So the h tags all have an ID which is the first part of the text with hyphens between it from the h3. In fact it's the entire h3. So that's pretty good. Let's try another one just to make sure it works. I'm going to click on this one and yep it's all being rendered right there. Awesome.

Get daily recaps from
Net Ninja

AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.