Skip to content
OVEX TECH
Education & E-Learning

Create Dynamic Pages for Your Books with Astro

Create Dynamic Pages for Your Books with Astro

How to Create Dynamic Pages for Your Books with Astro

In this guide, you’ll learn how to build individual pages for each book in your collection using Astro. We’ll cover setting up dynamic routes, fetching book data, and displaying your markdown content.

Overview

You’ve already set up your Astro project to use markdown files for your book content. You can see a list of your books, and each book has a link pointing to a specific page like /books/your-book-id. However, clicking these links currently leads to a 404 error because those pages don’t exist yet. This tutorial will show you how to create those pages automatically for every book in your collection. You’ll learn to make a special page that Astro can use to build unique pages for each book, showing its title and all its detailed content.

Prerequisites

  • An existing Astro project.
  • Your book content organized in markdown files within a collection (e.g., a src/content/books/ folder).
  • Basic understanding of Astro components and front matter.

Steps

  1. Create the Dynamic Route File

    First, you need to create a new page component that Astro will use for your individual book details. Inside your src/pages/books/ folder, create a new file. The name of this file is important for creating dynamic routes. To make a part of the URL dynamic, you need to put it in square brackets. For example, name the file [id].astro. This tells Astro that the id part of the URL (like /books/assassin-apprentice) can change for each book.

  2. Define Static Paths

    Astro needs to know which specific pages to build when you use a dynamic route. You tell Astro this by exporting a special function called getStaticPaths from your page component’s front matter. This function should return an array of objects. Each object in the array tells Astro about one page to create. For every book you have, you’ll need one object in this array.

    The getStaticPaths function needs to be async because it will fetch your book data. Inside this function, use Astro’s getCollection function to get all your books. You’ll need to import getCollection from Astro:content.

    Here’s how you get your books: const books = await getCollection('books');. This gives you an array where each item is an object representing one of your books.

  3. Map Books to Page Paths

    Now, you need to transform the list of books into the array of objects that getStaticPaths expects. You can do this by using the .map() method on your books array. For each book, you’ll return an object with two main properties: params and props.

    The params object tells Astro what value to use for the dynamic part of your URL. In our case, the dynamic part is id, so you’ll set params: { id: book.id }. The book.id here refers to the unique identifier for each book, which usually comes from its filename.

    The props object is used to pass data directly into your page component. You can pass the entire book object here so your page component has all the book’s information. So, you’ll set props: { book: book }.

    Your getStaticPaths function will look something like this:

    import { getCollection } from 'astro:content';
    
    export async function getStaticPaths() {
      const books = await getCollection('books');
      return books.map(book => ({
        params: { id: book.id },
        props: { book }
      }));
    }
  4. Create the Page Component Structure

    Next, you’ll build the actual page component using the data passed from getStaticPaths. Your [id].astro file will receive the book object as a prop. You can access it by destructuring it from Astro.props.

    Start by importing your base layout component, just like you would for any other page. Then, wrap your content within a container, perhaps a <div class="content">, to ensure consistent styling. For now, you can display the book’s title using an <h2> tag:

    {book.data.title}

    . Remember that book.data holds the front matter information from your markdown file.

  5. Display Markdown Content

    Your markdown files contain more than just front matter; they have the actual book descriptions and details. To render this markdown content as HTML within your page, Astro provides a special Content component. You need to import the render function from Astro:content.

    Inside your page component, you’ll call render(), passing the content entry (your book prop) to it. This function returns a component that contains all your markdown content, already converted into HTML elements like headings, paragraphs, lists, and more. You can then render this Content component directly in your template.

    Replace the <h2> tag with the Content component like this:

    
    // At the top of your [id].astro file
    import { Content} from 'astro:content';
    
    // Inside your component's return statement
    

    When Astro builds these pages, it automatically converts markdown headings into <h> tags with corresponding IDs, and markdown lists into <ul> or <ol> tags, making your content structured and accessible.

  6. Test Your Dynamic Pages

    Save your [id].astro file. Now, if you visit the links for your books (e.g., /books/your-book-id), you should see the individual book pages loading correctly. The title should appear, and below it, all the content from your markdown file will be displayed as formatted HTML. Try clicking on different book links to ensure each one generates a unique page with its correct information.

Expert Notes

The [id].astro filename is a convention. You could use [slug].astro or any other name within the brackets, as long as it matches the parameter name you expect in your route and in the params object within getStaticPaths. The book.id used in params: { id: book.id } is automatically generated by Astro based on the filename of your markdown file (e.g., assassin-apprentice.md would have an ID of assassin-apprentice).


Source: Astro Crash Course #10 – Dynamic Routes (YouTube)

Leave a Reply

Your email address will not be published. Required fields are marked *

Written by

John Digweed

2,810 articles

Life-long learner.