Omnira Docs v1.0.0

Data and detail pages

Things that appear in several places, such as rooms, courses, services, products, team members and blog posts, are stored once as records in the demo's data.json. Sections list them, and each record can get its own detail page automatically.

Records in data.json#

src/demos/hotel/data.json
{
  "rooms": [
    {
      "slug": "garden-suite",
      "title": "Garden Suite",
      "image": "placeholder",
      "price": "$420",
      "priceNote": "/ night",
      "subtitle": "Private terrace, outdoor shower",
      "meta": [{ "icon": "people", "text": "2 guests" }, { "icon": "arrows-fullscreen", "text": "48 m²" }]
    },
    { "slug": "ocean-villa", "title": "Ocean Villa", "…": "…" }
  ]
}

Each list (rooms here) is a collection. Every record needs a unique slug: lowercase letters, numbers and dashes. It becomes part of the page address. The other fields depend on which sections show the record; the demo guides list each collection's fields.

Listing records in a section#

Instead of typing items into a section, point it at a collection:

JSON
{ "type": "listings", "title": "Rooms & suites", "items": { "$data": "rooms" } }
OptionExampleMeaning
$data"rooms"Which collection.
limit3Show only the first N records.
where{ "category": "Suite" }Only records whose field matches. A list matches any of its values: { "city": ["Miami", "Austin"] }.
slugs["ocean-villa", "garden-suite"]Exactly these records, in this order.
exclude"@item"On a detail page, leave out the record being shown (for “You may also like” sections).

A single record can be used anywhere with "@rooms#ocean-villa".

Automatic detail pages#

A page file with "each" becomes a template: one page is created for every record in that collection.

src/demos/hotel/pages/room.json
{
  "each": "rooms",
  "title": "{item.title}",
  "description": "{item.subtitle}",
  "sections": [
    { "type": "detail", "item": "@item", "crumbs": [{ "label": "Home", "href": "index.html" }, { "label": "Rooms", "href": "rooms.html" }] },
    { "type": "listings", "title": "Other rooms", "items": { "$data": "rooms", "exclude": "@item", "limit": 3 } }
  ]
}
  • The file is room.json, so the pages are room-garden-suite.html, room-ocean-villa.html… ("prefix": "suite" would make them suite-… instead).
  • "@item" is the current record; "@item.title" one of its fields.
  • {item.title} inside a title or description is replaced with the field's text.
  • Every record with a detail page automatically gets an href, so cards in listings, services, blog, portfolio, products, team, tiles and slider link to it without you typing links.

Add, edit or remove a record#

  1. Open the demo's data.json and find the collection.
  2. To add one, copy a whole record (from { to }), paste it after a comma, change its slug and fields.
  3. Save. Its detail page is created and every section listing that collection includes it.
  4. To remove one, delete the record. Its page disappears on the next build; remove any links you typed to it by hand.

Examples by kind of record#

Blog post (article pages)
JSON
{
  "slug": "sourdough-starter",
  "title": "How we keep our sourdough starter alive",
  "image": "placeholder",
  "category": "Bakery",
  "date": "Sep 18, 2026",
  "author": "Maya Chen",
  "excerpt": "Twelve years, one jar, and the feeding schedule we swear by.",
  "html": "<p>Our starter is older than the café…</p><h3>Feeding</h3><p>…</p>"
}

Shown by blog cards; the article page uses the article section with "html": "@item.html". Write the body as simple HTML: <p>, <h3>, <ul>, <blockquote>.

Product (shop pages)
JSON
{
  "slug": "linen-shirt",
  "name": "Linen shirt",
  "category": "Men",
  "price": 79,
  "oldPrice": 99,
  "image": "placeholder",
  "gallery": ["placeholder", "placeholder"],
  "rating": 4.5,
  "reviews": 12,
  "colors": [{ "name": "Sand", "hex": "#d8c3a5" }, { "name": "Navy", "hex": "#1e3a5f" }],
  "sizes": ["S", "M", "L"],
  "description": "Washed European linen with a relaxed fit.",
  "specs": [["Material", "100% linen"], ["Care", "Machine wash cold"]]
}

Numbers for price are shown with the demo's currency (set in demo.json). Shown by products; the product page uses product-detail.

Team member (profile pages)
JSON
{
  "slug": "amara-okafor",
  "name": "Dr. Amara Okafor",
  "role": "Family dentist",
  "image": "placeholder",
  "bio": ["Amara has looked after families in Portland for twelve years."],
  "stats": [{ "number": "12", "label": "Years in practice" }],
  "list": ["Children's dentistry", "Nervous patients"],
  "phone": "+1 (555) 014-2201",
  "email": "amara@yourdomain.com"
}

Shown by team cards; the profile page uses the person section.

Service, course, room, tour, car or project (generic detail pages)

These use the detail section, which understands fields like title, image, gallery, price, meta, body, highlights, features, accordion (curriculum or itinerary), table and sidebar (booking form). Its reference page shows a full record.