Tutorial - Extend with Content Collections
Content collections are a powerful way to manage groups of similar content, such as blog posts. Collections help to organize your documents, validate your YAML frontmatter, and provide automatic TypeScript type-safety for all of your content (even if you don’t write any TypeScript yourself).
Get ready to…
- Move your folder of blog posts into
- Create a schema to define your blog post frontmatter
getCollection()to get blog post content and metadata
You will need an existing Astro project with Markdown or MDX files in the
This tutorial uses the Build a Blog tutorial’s finished project to demonstrate converting a blog to content collections. You can fork and use that codebase locally, or complete the tutorial in the browser by editing the blog tutorial’s code in StackBlitz.
You can instead follow these steps with your own Astro project, but you will need to adjust the instructions for your codebase.
We recommend using our sample project to complete this short tutorial first. Then, you can use what you have learned to create content collections in your own project.
Build a Blog Tutorial Code
In the Build a Blog introductory tutorial, you learned about Astro’s built-in file-based routing: any
.mdx file anywhere within the
src/pages/ folder automatically became a page on your site.
To create your first blog post at
https://example.com/posts/post-1/, you created a
/posts/ folder and added the file
post-1.md. You then added a new Markdown file to this folder every time you wanted to add a new blog post to your site.
Pages vs Collections
Even when using content collections, you will still use the
src/pages/ folder for individual pages, such as your About Me page. But, moving your blog posts to the special
src/content/ folder will allow you to use more powerful and performant APIs to generate your blog post index and display your individual blog posts.
At the same time, you’ll receive better guidance and autocompletion in your code editor because you will have a schema to define a common structure for each post that Astro will help you enforce. In your schema, you can specify when frontmatter properties are required, such as a description or an author, and which data type each property must be, such as a string or an array. This leads to catching many mistakes sooner, with descriptive error messages telling you exactly what the problem is.
Read more about Astro’s content collections in our guide, or get started with the instructions below to convert a basic blog from
Test your knowledge
Which type of page would you probably keep in
Which is not a benefit of moving blog posts to a content collection?
Content collections uses TypeScript…
Extending the blog tutorial with content collections
The steps below show you how to extend the final product of the Build a Blog tutorial by creating a content collection for the blog posts.
Upgrade to the latest version of Astro, and upgrade all integrations to their latest versions by running the following commands in your terminal:
The blog tutorial uses the
base(least strict) TypeScript setting. In order to use content collections, you must set up TypeScript for content collections either by using the
strictestsetting, or by adding two options in
In order to use content collections without writing TypeScript in the rest of the blog tutorial example, add the following two TypeScript configuration options to the config file:
Create a collection for your blog posts
Create a new collection (folder) called
Move all your existing blog posts (
src/pages/posts/into this new collection.
src/content/config.tsfile to define a schema for your
postsCollection. For the existing blog tutorial code, add the following contents to the file to define all the frontmatter properties used in its blog posts:
Generate pages from a collection
Create a page file called
src/pages/posts/[...slug].astro. Your Markdown and MDX files no longer automatically become pages using Astro’s file-based routing when they are inside a collection, so you must create a page responsible for generating each individual blog post.
Add the following code to query your collection to make each blog post’s slug and page content available to each page it will generate:
Render your post
<Content />within the layout for Markdown pages. This allows you to specify a common layout for all of your posts.
layoutdefinition in each individual post’s frontmatter. Your content is now wrapped in a layout when rendered, and this property is no longer needed.
Anywhere you have a list of blog posts, like the tutorial’s Blog page (
src/pages/blog.astro/), you will need to replace
getCollection()as the way to fetch content and metadata from your Markdown files.
You will also need to update references to the data returned for each
post. You will now find your frontmatter values on the
dataproperty of each object. Also, when using collections each
postobject will have a page
slug, not a full URL.
The tutorial blog project also dynamically generates a page for each tag using
src/pages/tags/[tag].astroand displays a list of tags at
Apply the same changes as above to these two files:
- fetch data about all your blog posts using
getCollection("posts")instead of using
- access all frontmatter values using
- create a page URL by adding the post’s
The page that generates individual tag pages now becomes:
Try it yourself - Update the query in the Tag Index page
Import and use
getCollectionto fetch the tags used in the blog posts on
src/pages/tags/index.astro, following the same steps as above.
Show me the code.
- fetch data about all your blog posts using
Update any frontmatter values to match your schema
If necessary, update any frontmatter values throughout your project, such as in your layout, that do not match your collections schema.
In the blog tutorial example,
pubDatewas a string. Now, according to the schema that defines types for the post frontmatter,
pubDatewill be a
To render the date in the blog post layout, convert it to a string:
Update RSS function
Lastly, the tutorial blog project includes an RSS feed. This function must also use
getCollection()to return information from your blog posts. You will then generate the RSS items using the
For the full example of the blog tutorial using content collections, see the Content Collections branch of the tutorial repo.Learn