orbiter:collections
A Vite virtual module that gives you typed access to your published content in Astro pages. Snapshots at build time — zero runtime database access.
Setup
The module is available automatically after adding @a83/orbiter-integration to your Astro config. No additional imports needed.
API
import { getCollection, getEntry, getLocaleCollection, getLocaleEntry, locale, locales } from 'orbiter:collections'; getCollection(name)
Returns all published entries in a collection, sorted by updated_at descending.
const posts = await getCollection('posts');
// → Entry[] getEntry(collection, slug)
Returns a single entry by slug, or null if not found or not published.
const post = await getEntry('posts', 'my-first-post');
// → Entry | null getLocaleCollection(name, locale?)
Returns entries for a specific locale. Entries follow the slug--locale convention. If locale is omitted, returns all entries including variants.
const dePosts = await getLocaleCollection('posts', 'de');
// → Entry[] where slug ends with '--de' getLocaleEntry(collection, baseSlug, locale)
Returns a locale variant of an entry, falling back to the base entry if the variant doesn't exist.
const post = await getLocaleEntry('posts', 'my-post', 'de');
// → returns 'my-post--de' if it exists, otherwise 'my-post' locale and locales
import { locale, locales } from 'orbiter:collections';
// locale → 'en' (default locale from Settings)
// locales → ['en', 'de'] (all configured locales) Entry shape
{
id: string, // UUID
slug: string, // URL-safe identifier
status: 'published',
created_at: string, // ISO datetime
updated_at: string, // ISO datetime
data: {
// all fields from your schema, e.g.:
title: string,
body: string, // richtext → rendered HTML
image: string, // media field → UUID
tags: string[], // array field
author: Entry, // relation → resolved Entry object
}
} Static paths
---
export async function getStaticPaths() {
const posts = await getCollection('posts');
return posts.map(post => ({ params: { slug: post.slug } }));
}
const post = await getEntry('posts', Astro.params.slug);
--- Multilingual static paths
---
import { getCollection, locales } from 'orbiter:collections';
export async function getStaticPaths() {
const posts = await getCollection('posts');
const base = posts.filter(p => !p.slug.includes('--'));
return base.flatMap(post =>
locales.map(loc => ({
params: { slug: post.slug, lang: loc }
}))
);
}
--- Media URLs
<img src={`/orbiter/media/${post.data.image}`} alt="" /> Works regardless of which media backend is configured. For external backends, /orbiter/media/[id] issues a 302 redirect to the CDN or original URL.
orbiter:db
A second virtual module that exposes the resolved pod path for use in your own Astro server routes or API endpoints.
import { podPath } from 'orbiter:db';
import { openPod } from '@a83/orbiter-core';
// src/pages/api/my-endpoint.js
export async function GET() {
const db = openPod(podPath);
const entries = db.getEntries('posts');
db.close();
return new Response(JSON.stringify(entries), {
headers: { 'Content-Type': 'application/json' }
});
} orbiter:db only works in server-rendered routes (output: 'server' or 'hybrid'). In static output there is no runtime to open the pod.Relation fields
Relation fields are resolved at build time. The raw UUID reference is replaced with the full Entry object of the related entry.
{posts.map(post => (
<div>
<h2>{post.data.title}</h2>
<p>by {post.data.author?.data?.name}</p>
{post.data.categories?.map(cat => (
<span>{cat.data.name}</span>
))}
</div>
))}