Skip to Content
FeaturesModels

Models

A model defines the structure and behavior of your content in Foir. Every piece of data — pages, blog posts, bookings, product records, configurations — is stored as a record that belongs to a model.

Overview

A model is a schema definition that controls what data your records can hold and how they behave. Each model has:

  • Key — A unique identifier used in APIs and configuration (e.g., page, blog-post, booking)
  • Name — A display name shown in the admin dashboard
  • Fields — The schema that defines the shape of each record (see Field Types)
  • Config — Capability flags that control versioning, publishing, variants, and more

Model Capabilities

Every model has a config object that enables or disables features:

CapabilityDescriptionDefault
versioningTrack change history; each update creates a new versionOff
publishingDraft/publish workflow; records are not live until explicitly publishedOff
variantsMultiple content versions for different audiences (device, segment, market)Off
inlineModel can be used as a field type inside other modelsOff
publicApiRecords are accessible via the public APIOff
customer_scopedRecords are owned by individual customersOff

These capabilities are mix-and-match. A model can have versioning without variants, publishing without versioning, or none at all.

Use Case Categories

Simple Data (no capabilities) — For application data that needs direct read/write without overhead. Records are updated in place with no drafts, versions, or publishing step. Examples: form submissions, bookings, app configuration, feature flags, counters.

Published Content (versioning + publishing) — For content that needs a review workflow. Each edit creates a new version, and content stays in draft until explicitly published. Examples: blog posts, announcements, documentation, policies.

Personalized Content (versioning + publishing + variants) — For content that changes based on audience. Variants target different devices, markets, or customer segments, and each variant has its own version history. Examples: landing pages, navigation menus, promotional banners, product descriptions.

Reusable Components (inline mode) — For models used as field types inside other models. When inline is enabled, the model’s key becomes available as a field type. Examples: hero banners, CTAs, testimonials, product cards.

Quick Reference

Use CaseVersioningPublishingVariants
Blog postsYesYesNo
Landing pagesYesYesYes
Navigation menusYesYesYes
Form submissionsNoNoNo
App configurationNoNoNo
Event bookingsNoNoNo
Hero banners (inline)NoNoNo

In the Admin

  1. Go to Settings > Models
  2. Click Create Model
  3. Fill in:
    • Name: e.g., “Blog Post”
    • Key: auto-generated from the name (e.g., blog-post), or set manually
  4. Configure capabilities (versioning, publishing, variants, etc.)
  5. Add fields to the schema
  6. Optionally enable Public API access
  7. Click Save

Model schemas track changes with version history. When you edit a model’s fields, a new schema version is created, and you can restore a previous schema version if needed.

Via the CLI

List all models

foir models list

Get a model by key

foir models get blog-post

Create a model

foir models create --data '{ "key": "blog-post", "name": "Blog Post", "pluralName": "Blog Posts", "fields": [ { "key": "title", "name": "Title", "type": "text", "required": true }, { "key": "slug", "name": "Slug", "type": "text", "required": true }, { "key": "body", "name": "Body", "type": "content" } ], "config": { "versioning": true, "publishing": true, "publicApi": true } }'

You can also create models from a directory of JSON files, with optional upsert behavior:

foir models create --dir ./models --upsert

Update a model

foir models update --data '{ "id": "mod_abc123", "name": "Blog Post", "fields": [...] }'

Delete a model

foir models delete mod_abc123

List schema versions

foir models versions mod_abc123

Via the API

List models

query { models(limit: 50) { items { id key name pluralName description category fields config } total } }

The config field returns the capability flags:

{ "versioning": true, "publishing": true, "variants": true, "inline": false, "publicApi": true }

Only models with config.publicApi: true are accessible through the public API.

Query parameters

ParameterTypeDescription
searchStringSearch models by name or key
filters[FilterInput!]Filter conditions
categoryStringFilter by category
limitIntMaximum results to return
offsetIntResults to skip

Config System

Models can also be defined in code using defineModel in your foir.config.ts file. This is useful for version-controlling your model schemas alongside your application code.

See Model Configuration for the full reference.

Best Practices

  • Choose the minimal set of capabilities each model needs. Simpler models are faster and easier to work with.
  • Use clear, descriptive keys. The key is permanent and used throughout your APIs and configuration.
  • Enable publicApi only on models that need external access. Keep internal data models private.
  • Use the --upsert flag with foir models create --dir to safely sync model definitions from your codebase.
  • Track schema changes with meaningful descriptions so you can review and roll back if needed.
Last updated on