Curvea

Data and Content

Markdown Content

Curvea includes a Markdown content system.

Markdown files live in:

src/content/<collection>

Example:

src/content/blog/my-post.md

Content page structure

A content collection is connected to page templates by matching folder names.

Example:

src/pages/blog/Index.csc
src/pages/blog/[slug].csc
src/content/blog/my-post.md

This creates:

/blog
/blog/my-post

Collection index page

For Index.csc, Curvea exposes collection data:

@page

<h1>Blog</h1>

@for post in collection.items
  <a href="{{ post.route }}">{{ post.title }}</a>
@end

Dynamic content page

For [slug].csc, Curvea exposes the matched Markdown file as page.

@page

<article>
  <h1>{{ page.title }}</h1>
  {{ page.content }}
</article>

Frontmatter

Markdown files can include frontmatter:

---
title: My Post
description: A short description.
date: 2026-05-18
draft: false
---

# My Post

Content here.

Drafts

Draft behavior differs by environment:

  • dev includes drafts
  • build excludes drafts

A draft is a Markdown file with:

draft: true

Reading time

Curvea calculates reading time using 200 words per minute.

The value is exposed as:

{{ page.readingTime }}

Example output:

3 min read

Previous and next

Content pages receive sibling links:

{{ page.previous.title }}
{{ page.next.title }}

These can be null when there is no previous or next page.

Sorting

Sorting depends on collection name.

blog

Blog entries sort by date descending, then file name.

docs

Docs entries sort by numeric order, then title, then file name.

Other collections

Other collections sort by file name.