siterealContent & data

A content type is one schema.

Define it once and the types, the editing form and the typed queries all come out of the same definition. Collections are files in your repository, so the content travels with the code.

// src/content.config.ts
const posts = defineCollection({
  loader: glob({ pattern: '**/*.md',
                 base: './src/content/posts' }),
  schema: z.object({
    title: z.string(),
    date: z.coerce.date(),
    tags: z.array(z.string()),
    draft: z.boolean().default(false),
  }),
});

One definition, four things.

  1. 01Typeswhat your editor reads
  2. 02Formwhat the Content Hub renders
  3. 03Querywhat a loop emits into the page
  4. 04Validationwhat every entry is written through

01Collections

A collection is a table you already know how to read.

Every collection sits in the rail with its count, and its entries are rows: a title, a status you switch between Live and Draft, and one column per field. Switch a collection public and each entry becomes a page with its own route.

02Fields

Thirteen field types, one click each.

Add field opens the whole list. Pick one and it is a column in the table, an input in every entry and a key a loop binds to — Title and Slug ship with every collection, and a group or a repeating item holds fields of its own.

03Loops

A loop is a query, and what repeats is ordinary markup.

Wrap a card in a Loop, point it at a collection, a JSON file or an expression, and bind the fields you want. The page emits a real query and a real .map() — the cards below are what the one card above them turns into.

04Storage

Files by default. Rows when files run out.

Default

Files in git

Markdown, MDX, JSON or YAML in the repository: versioned with the code, diffable, and static by default. Nothing to host, nothing to migrate.

  • src/content/<type>/<slug>.md
  • History and review through git
  • Builds with the network down
Database addon

Rows in a database

For the three things files cannot do: editing without a deploy, data a visitor writes, and a collection large enough to need a query.

  • libSQL or PostgreSQL, yours
  • An ordinary Drizzle project in src/db
  • Loops still read at build time
tags: ["release"]

Taxonomies are fields

Tags and categories are terms assigned in the entry form, so a loop filtered by one is a query over the same file — no join table, no plugin.

<Condition>

Conditions are elements

Wrap anything in a Condition and it emits the expression you wrote. Several clauses fold left to right, every step in brackets.

/uploads/hero.jpg

Media is the repository

Assets live under public/ with their alt text, offered as a picker, and photographs ship with a real srcset. Nothing is uploaded anywhere.

Start building the sites you’ve always wanted.

Seven days free, on your machine — and every site you build is real Astro in your own repository, yours from the first save.