Skip to main content
Collections in OlonJS are typed registries of content entities. Each collection is defined by a Zod schema that enforces the shape of every item, and stored as a JSON record on disk. The framework ships with two built-in collections — posts and tags — but you can add as many as your project needs. Collections power dynamic pages, feed section data through $ref pointers, and are the foundation of cross-collection relations.

What is a collection?

A collection is a Record<string, Item> where each value is a typed object that conforms to a Zod schema. Items are addressed by their key — the string that appears as the property name in the JSON file. That key also becomes the URL slug for the item’s dynamic page.
Collection file structure
Each key in the JSON record doubles as the item’s id. The designing-with-constraints key in posts.json means the post is accessible at /posts/designing-with-constraints.

Collection schema

The schema is the authoritative contract for every item in a collection. Here is the PostSchema from src/collections/posts/schema.ts:
src/collections/posts/schema.ts
The fields on PostSchema are: The describe('ui:text') calls are hints consumed by Studio’s Inspector panel to render the correct input widget for each field.

The CollectionRegistry

The CollectionRegistry is a single object that tells the OlonJS engine which collections exist and what Zod schema validates each one. Register every collection here so the engine can validate data, resolve $ref pointers, and power the Studio editor.
src/lib/CollectionRegistry.ts
The key (posts, tags) must match the source field in any collection block on a dynamic page (see Pages) and the filename convention under src/data/collections/.

Using collections in sections

Section data fields can reference collection data through $ref pointers instead of inlining content. The engine resolves the pointers before the section component receives its props. There are two pointer forms: Collection-level ref — resolves to the entire Record<string, Item> object. Use this when a section needs the full collection, such as a list component that will filter or paginate on the client. Item-level ref — resolves to a single item by key. The fragment after #/ is the item key.
Collection-level $ref in a section
Item-level $ref in a post's tags array
The path in a $ref is relative to the file that contains it. From src/data/collections/posts/posts.json, ../tags/tags.json#/design resolves to the design key in src/data/collections/tags/tags.json.
OlonJS resolves all $ref pointers as part of the build process, so your production visitor site always receives fully resolved data — no pointer look-ups happen at request time. Studio shows the raw pointer values in the Inspector and resolves them live in the preview panel, so you always see current data while authoring without waiting for a deploy.

Adding a new collection

Follow these steps to add a collection to your OlonJS project:
  1. Create the schema — add src/collections/my-collection/schema.ts and export a Zod schema that extends BaseCollectionItem. Export a z.record(z.string(), MyItemSchema) as the collection schema.
  2. Add the data file — create src/data/collections/my-collection/my-collection.json as a Record<string, MyItem> JSON object. Use the item key as the id field value.
  3. Register the collection — open src/lib/CollectionRegistry.ts and add your new collection schema:
src/lib/CollectionRegistry.ts
Your collection is now available for $ref pointers in page bundles and section data, and Studio’s Inspector can display its items in relation pickers.