Content model

Rigel has separate content models for structured documents, article collections and existing copy pages. Declaring content does not create website routes or discover bindings in arbitrary components. Your Astro templates read the data and render the site.

Documents and sections

Use defineSchema, defineDocument and defineObject from @rigel-cms/rigel/content. A document type declares a unique name, a content folder and fields. See Getting started for a complete page example.

Schema scalar types are string, text, markdown, boolean, number, date, image, url, color, code and password. Structured fields use object, array or reference. Mark a field required: true when editors must supply a value; use initialValue for editable defaults.

These types describe the editing controls, not protected storage. A password field only masks its input; content files still store the value as data. Keep credentials out of content files and public builds.

Named sections belong in schema.objects:

const hero = defineObject({
  name: "hero",
  title: "Hero",
  type: "section",
  fields: [
    { key: "heading", label: "Heading", type: "string", required: true, initialValue: "Hello" },
  ],
});

Add hero to objects, then add this field to a page document’s fields:

{
  key: "sections",
  label: "Sections",
  type: "array",
  items: [{ type: "object", name: "hero" }],
}

A document’s template: [{ type: "hero" }] seeds new sections. This schema template is content initialization, not a preview URL. Array items keep stable _key values; named section objects also store _type. Preserve those identities when editing JSON by hand. Templates need keyed preview bindings to show inserted or reordered sections before Save.

Document JSON stores _id, _type, slug and its field values. A page at src/content/pages/about.json uses _id: "page:about", _type: "page" and slug: "about". Use unique lowercase kebab-case slugs and avoid collisions with routes the site already owns.

Shared records

Set shared: true on a document type for reusable data such as authors or site settings. Shared records use a form rather than a website canvas. singleton: true opens the existing single record directly; creatable: false prevents editors from adding records of that type. Document deletion remains developer-managed.

A schema reference field declares to as an array of type names:

{ key: "author", label: "Author", type: "reference", to: ["author"] }

Its stored value is an object such as { "_ref": "author:alex" }. Resolve it in Astro with derefDocument() from virtual:rigel-content. The same module exposes documents and getDocument("page:about"). References do not expand themselves inside arbitrary templates.

Article collections

Configure article collections in rigel({ collections: [...] }):

collections: [
  {
    name: "news",
    label: "News",
    folder: "src/content/news",
    fields: [
      { key: "title", label: "Title", type: "string", required: true },
      { key: "date", label: "Date", type: "date", required: true },
      { key: "draft", label: "Draft", type: "boolean" },
      { key: "tags", label: "Tags", type: "tags" },
    ],
    columns: ["title", "date", "tags"],
  },
]

Each article file is JSON with { frontmatter, body }. frontmatter contains the configured metadata. body is Lexical editor state, not a Markdown or MDX string. Create articles in the editor and use renderArticle from @rigel-cms/rigel/article to render their saved bodies. The Markdown view is a read-only projection.

Collection field types are string, text, boolean, date, tags, markdown, image and reference. Collection references differ from schema references: use to: "author", and the stored value is an ID string. multiple: true stores an array of ID strings. A fixed options array can replace to for developer-managed choices.

Rigel validates configured collection fields on load and before Save. Required strings need non-whitespace text, required arrays need an item and false is a valid required boolean. Dates use real YYYY-MM-DD dates. Existing unknown properties are preserved.

Rigel does not discover or execute Astro’s src/content.config.ts schemas. If your site also loads these files through Astro collections, align both schemas and their requiredness. A Rigel field declaration does not convert an existing Markdown collection to JSON articles.

Drafts and SEO

Rigel adds missing description, metaTitle and ogImage declarations to website documents and article collections. Non-shared document types also receive a missing draft declaration. New collection drafts initialize configured fields, including the automatic SEO strings; existing entries are not backfilled.

The host must filter drafts and render SEO fields. For document routes, the starter uses:

const pages = documents.filter(
  (doc) => doc.type === "page" && (import.meta.env.DEV || doc.data.draft !== true),
);

Use metaTitle for the browser title with a fallback to the page or article title. Render description in the description meta tag and ogImage in social image tags. Editing these fields alone does not alter a host template that ignores them. Apply equivalent draft filtering to article routes and feeds.

Existing defineCopy pages remain supported. Their modules declare grouped fields and data-only values. GitHub mode accepts literal defineCopy({ ... }) data, not computed JavaScript. New structured sites can use JSON schema documents without migrating every existing copy module at once.

Documentation

On this page