The team at Astro just released a big change to how they handle content in their Content Layer in Astro v15. Now, instead of only having an internal content loader, they’ve opened the door for there to be custom content loaders.
To celebrate their launch today, we’ve got our own announcement to go with it: the Hygraph Content Loader for Astro.
The Hygraph Content Loader takes advantage of the new Content Layer API and provides a consistent data layer for your Hygraph Data and Astro Data. Instead of making requests per page or layout, you can create one configuration element for each type of data and have it ready at build time.
#Implementation
To start, we need to install the loader in our Astro project.
npm install @hygraph/astro-content-loader
In your src/content/config.ts
file, you can import the package and use Astro’s defineCollection
method to define a new collection with a specific set of Hygraph data and even validate with Zod the types and amount of data coming back from Hygraph for your project.
import { defineCollection, z } from 'astro:content';import { HygraphLoader } from '@hygraph/hygraph-astro-loader';const withLoader = defineCollection({loader: HygraphLoader({endpoint: import.meta.env.ASTRO_HYGRAPH_ENDPOINT,fields: ['id', 'title', 'slug', {body: ['text']}],operation: 'pages'}),schema: z.object({id: z.string(),title: z.string().min(1, { message: 'Title must be at least 1 character long' }),slug: z.string(),body: z.object({text: z.string()})})})
Once you've defined your collection with the Hygraph loader, you can use it in your Astro components just like any other content collection. This seamless integration allows for a smooth development experience and consistent data handling across your project.
Here's an example of how you might use the Hygraph content in an Astro page to get all pages from our collection:
---import { getCollection } from 'astro:content';const pages = await getCollection('pages');---<ul>{pages.map((page) => (<li><a href={`/pages/${page.slug}`}>{page.data.title}</a></li>))}</ul>
Or we can loop through them to create the pages:
---import Main from "../../layouts/main.astro";import { getCollection, render } from 'astro:content';export async function getStaticPaths() {const pageEntries = await getCollection('page');return pageEntries.map(page => ({params: { slug: page.data.slug }, props: { page: page },}));}const { page } = Astro.props---<!-- Renders the homepage with a title and a page fetched from the Hygraph --><Main title={page.data.title}><div class="m-12"><h1 class="text-5xl font-bold mb-4">{page.data.title}</h1><p class="text-lg mb-8">{page.data.body.text}</p><p><a href="/" class="underline">Back to homepage</a></p></div></Main>
This approach offers several advantages:
- Type Safety: With Zod schema validation, you ensure that the data coming from Hygraph matches your expectations, reducing runtime errors.
- Performance: By default, Astro encourages static page generation. This is great for your site’s overall performance, but Astro also provides server-rendered functionality, as well. Pages built using the Content Layer API are also more performant than using standard fetch methods for each SSR page.
- Developer Experience: The consistent API across different content sources (local, Hygraph, and other third parties) simplifies the development process and makes your code more maintainable. By configuring, we also have less boilerplate per page required. This increases the efficiency of developers creating new pages from this data.
As the Hygraph Content Loader matures, we anticipate even more features that will enhance your development workflow. Stay tuned for updates on incremental builds and improved caching mechanisms, which will further optimize your build process and site performance.
We're excited to see how the Astro community leverages this new integration with Hygraph. If you have any feedback or feature requests, please don't hesitate to reach out to our team or contribute to the project on GitHub.
Blog Author