@ryandejaegher/astro-collections
v0.1.0
Published
Reusable, extendable Astro content collections for pages and posts.
Readme
@ryandejaegher/astro-collections
Reusable, extendable Astro content modeling toolkit for Markdown and MDX.
Install
npm install @ryandejaegher/astro-collections astroReleases are published from the repository's GitHub Actions workflow using npm trusted publishing (OIDC), so no long-lived npm token is required.
Configure
Create src/content.config.ts in the consuming Astro project:
import { createPagesCollection } from '@ryandejaegher/astro-collections';
import { z } from 'astro/zod';
const pages = createPagesCollection({
base: './src/content/pages',
schema: (defaults) =>
defaults.extend({
eyebrow: z.string().optional(),
accent: z.enum(['violet', 'cyan', 'amber']).default('violet'),
}),
});
export const collections = { pages };Posts
Use createPostsCollection() for dated content:
import { createPostsCollection } from '@ryandejaegher/astro-collections';
import { z } from 'astro/zod';
const posts = createPostsCollection({
schema: (defaults) =>
defaults.extend({
category: z.string().optional(),
}),
});
export const collections = { posts };Pages and posts remain the original content-oriented presets. Pages provide title, optional description/slug, draft, and layout; posts add required pubDate, optional updatedDate/author, and defaulted tags.
Structured collections
The toolkit also exports these factories:
| Factory | Default model |
| --- | --- |
| createProductsCollection() | Name, price, currency, SKU, URL, tags |
| createEventsCollection() | Title, start/end dates, location, URL, tags |
| createPeopleCollection() / createAuthorsCollection() | Name, bio, avatar, role, URL |
| createPortfolioItemsCollection() | Title, client, role, year, URL, featured, tags |
| createCaseStudiesCollection() | Title, client, summary, outcome, year, URL, tags |
| createRecipesCollection() | Title, preparation/cook time, servings, ingredients, steps, tags |
| createTaxonomiesCollection() | Name, slug, description, optional parent reference |
These models intentionally do not include page presentation fields such as layout. They describe structured data; the consuming app decides how that data is rendered.
Products, authors, taxonomies, and relationships
Collection names are app-owned. Pass them to references so the package can use Astro's native reference() schema with the names in your collections object:
import {
createAuthorsCollection,
createProductsCollection,
createTaxonomiesCollection,
} from '@ryandejaegher/astro-collections';
import { z } from 'astro/zod';
const authors = createAuthorsCollection({
base: './src/content/authors',
});
const topics = createTaxonomiesCollection({
base: './src/content/topics',
references: { taxonomies: 'topics' },
});
const products = createProductsCollection({
base: './src/content/products',
references: {
authors: 'authors',
taxonomies: 'topics',
},
schema: (defaults) =>
defaults.extend({
vendor: z.string().optional(),
// Existing fields can be overridden too.
name: z.string().min(1).max(80),
}),
});
export const collections = { authors, topics, products };The corresponding product frontmatter can use IDs:
---
name: Astro camera
authors: [ryan]
categories: [photography]
---At runtime, Astro resolves those values as references to the configured authors and topics collections. Other relationship options include people, products, events, portfolioItems, caseStudies, and recipes. Use collectionReference() or collectionReferenceArray() when defining a custom relationship in an extension.
Modeling philosophy
- Presets provide useful validation and defaults without claiming ownership of an app's content structure.
- Shared primitives (
titleSchema,nameSchema,descriptionSchema,slugSchema,draftSchema,tagsSchema,urlSchema, and date schemas) make custom models consistent. - Every factory accepts a
schemacallback, so consumers can add fields, override fields, or return an entirely new schema. - Collection paths, file patterns, loaders, and relationship collection names stay configurable.
- Pages/posts are content presets; products, events, people, portfolio items, case studies, recipes, and taxonomies are structured-data presets.
