roadmap
roadmap copied to clipboard
Content Layer
Summary
Creates a successor to content collections with expanded use cases, including remote data sources and improved performance.
// src/content/config.ts
import { defineCollection, z } from "astro:content";
import { glob, file } from "astro/loaders";
import { feedLoader } from "@ascorbic/feed-loader";
// Loaders can be defined inline
const countries = defineCollection({
type: "data",
loader: async () => {
const response = await fetch("https://restcountries.com/v3.1/all");
const data = await response.json();
// Must return an array of entries with an id property, or an object with IDs as keys and entries as values
return data.map((country) => ({
id: country.cca3,
...country,
}));
},
});
// Loaders can also be distributed as packages
const podcasts = defineCollection({
type: "content",
loader: feedLoader({
url: "https://feeds.99percentinvisible.org/99percentinvisible",
}),
});
// The `glob()` loader loads multiple files, with one entry per file
const spacecraft = defineCollection({
type: "content",
loader: glob({ pattern: "*.md", base: "src/data/spacecraft" }),
// A schema is optional, but provides validation and type safety for data.
// It can also be used to transform data before it is stored.
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string(),
heroImage: image().optional(),
}),
});
// The `file()` loader loads multiple entries from one file
const dogs = defineCollection({
type: "data",
loader: file("src/data/dogs.json"),
schema: z.object({
id: z.string(),
breed: z.string(),
temperament: z.array(z.string()),
}),
});
export const collections = { spacecraft, dogs, countries, podcasts };