Docs

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>
))}