Announced in June 2024, the Astro Content Layer API is a new approach to working with local and remote content sources in Astro. Built upon the Content Collections API, the Content Layer API is designed to be more flexible and powerful and is generally available in Astro 5.0 and later.
This guide will show you how to use this new feature to create a page in your Starlight documentation website listing the recent GitHub releases for a specific repository. To do so, we will use the Astro feed loader to fetch the latest releases from an Atom feed and display them on a custom page.
Prerequisites
You will need to have an existing Starlight website.
Install the feed loader
Start by installing the @ascorbic/feed-loader
package:
npm install @ascorbic/feed-loader
pnpm add @ascorbic/feed-loader
yarn add @ascorbic/feed-loader
bun add @ascorbic/feed-loader
ni @ascorbic/feed-loader
Load recent GitHub releases
To load content with the Content Layer API, the Astro feed loader can be used when defining a collection in the src/content.config.ts
file.
The loader takes a URL as input which will be fetched and parsed as an Atom feed. GitHub provides an Atom feed for the releases of a repository using the following URL format: https://github.com/OWNER/REPO/releases.atom
.
The following example defines a new collection named releases
that fetches the latest releases of the Starlight repository:
import { defineCollection } from 'astro:content'import { docsLoader } from '@astrojs/starlight/loaders'import { docsSchema } from '@astrojs/starlight/schema'import { feedLoader } from '@ascorbic/feed-loader'
export const collections = { docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), releases: defineCollection({ loader: feedLoader({ url: 'https://github.com/withastro/starlight/releases.atom', }), }),}
List recent releases
To list the recent releases, Astro’s file-based routing can be used to create a new page in the src/pages/
directory.
The new page will use the <StarlightPage />
component to render the content using the default Starlight layout and the getCollection()
function to query the releases
collection created earlier.
---import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'import { getCollection } from 'astro:content'
// Query the releases collection to get the recent releases.const releases = await getCollection('releases')---
<StarlightPage frontmatter={{ title: 'Recent Releases' }}> { releases.map((release) => { // Loop over the releases to display their titles. return <h2>{release.data.title}</h2> }) }</StarlightPage>
The above example will render the following content:
Recent Releases
@astrojs/starlight@0.27.1
@astrojs/starlight-markdoc@0.1.0
@astrojs/starlight@0.27.0
@astrojs/starlight@0.26.4
@astrojs/starlight@0.26.3
@astrojs/starlight@0.26.2
@astrojs/starlight@0.26.1
@astrojs/starlight@0.26.0
@astrojs/starlight@0.25.5
@astrojs/starlight@0.25.4
Display release details
Instead of only listing the release titles, we can render a custom Astro component to display more information about each release.
---import { render, type CollectionEntry } from 'astro:content'
interface Props { release: CollectionEntry<'releases'>}
// Render the release content.const { release } = Astro.propsconst { Content } = await render(release)---
<article> <h2 id={release.id}>{release.data.title}</h2> <Content /></article>
The above example will render the following content:
Fill in the table of contents
When using the <StarlightPage />
component, the table of contents will not be automatically filled with the content of the page.
To do so, the headings
property can be used to specify an array of headings to include in the table of contents.
---import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'import { getCollection } from 'astro:content'import Release from '../components/Release.astro'
const releases = await getCollection('releases')// Loop over the releases to create the table of contents.const headings = releases.map((release) => ({ slug: release.id, text: release.data.title, depth: 2,}))---
<StarlightPage frontmatter={{ title: 'Recent Releases' }} {headings}> {releases.map((release) => <Release {release} />)}</StarlightPage>
Up to you to customize the content of the release details component to display more information, e.g., the release date, the author, etc.
You can find the complete source code of this guide in this StackBlitz example.