NomaCMS

Key Concepts

Key Concepts

Understanding the core building blocks of NomaCMS will help you model content effectively and get the most out of the platform.

Projects

A project is the top-level container for everything in NomaCMS. Each project gets its own isolated database, API endpoints, settings, and credentials. One project typically maps to one website, app, or product.

You can create multiple projects under your account. For example, a marketing site, a mobile app backend, and a documentation site can each be separate projects.

Every project has:

  • A unique Project ID (UUID) used in all API requests
  • Its own set of collections, entries, and assets
  • Independent locale configuration for multilingual content
  • Project auth and API keys settings

Collections

Collections define the structure (schema) of your content. Think of them as content types or blueprints. A "Blog Posts" collection defines what a blog post looks like. A "Products" collection defines what a product looks like.

Each collection has:

  • Name - Human-readable label (e.g. "Blog Posts")
  • Slug - URL-friendly identifier used in the API (e.g. blog-posts)
  • Fields - The schema definition (title, content, image, etc.)
  • Entries - The actual content items created from this schema

Singleton collections

Most collections are lists that hold many entries (blog posts, products, team members). But some content is one-of-a-kind: your homepage hero section, site-wide settings, an about page.

For these, NomaCMS supports singleton collections. A singleton holds exactly one entry. When you fetch it through the API, you get the entry directly instead of an array.

// List collection - returns an array (or a paginator object when using paginate)
const posts = await noma.content.list("blog-posts")
 
// Singleton collection (is_singleton on the collection) - list returns a single entry object
const homepage = await noma.content.list("homepage")
// homepage = { uuid: "...", fields: { ... }, ... }

Fields

Fields define the data shape of each entry in a collection. NomaCMS supports 16 field types:

TypeDescriptionRepeatable
textSingle-line text (titles, headings)Yes
longtextMulti-line text area (descriptions, excerpts)Yes
richtextMarkdown-based rich text editor (articles, body content)No
slugAuto-generated URL slug, can attach to a text fieldNo
emailEmail input with format validationYes
passwordEncrypted password fieldNo
numberNumeric input (integers, decimals)Yes
enumerationDropdown of predefined valuesNo
booleanTrue/false toggleNo
colorColor picker (hex/rgb)Yes
dateCalendar date picker, optionally with timeYes
timeTime pickerYes
mediaFile selector from the asset library (single or multiple)No
relationLink to entries in another collection (one-to-one or one-to-many)No
jsonRaw JSON dataNo
groupContainer for nested child fields (repeatable groups supported)Yes

Fields that are marked Repeatable can be configured to accept multiple values (e.g. a "tags" text field that holds an array of strings).

Field options

Every field has options that control its behavior:

  • hideInContentList - Hide this field from the content list view in the dashboard
  • hiddenInAPI - Exclude this field from API responses
  • repeatable - Allow multiple values (where supported)

Some field types have additional options. For example, enumeration has a list of allowed values, media has a type for single vs. multiple files, and relation has a collection and type for the relationship kind.

Validations

Validation rules are stored per field (for example validations.required with { status: boolean, message: string }). In the API and SDK, that is separate from options (editor and display settings).

  • required - Entry cannot be saved without this field when status is true
  • unique - Value must be unique across all entries in the collection
  • charcount - Character count constraints (min, max, or between). For number fields, this acts as numeric min/max limits.

Field names

Field names must be in kebab-case: lowercase letters, numbers, and hyphens only. Examples: title, blog-post, meta-description, featured-image.

Entries

Entries are the actual content items stored in a collection. Each entry contains values for the fields defined by its collection.

Every entry has:

  • UUID - Unique identifier
  • Locale - Which language/locale this entry is in
  • State - Either draft or published
  • Fields - The content data keyed by field name
  • Timestamps - created_at and updated_at (optional in API responses)

The state field is a built-in system property. You don't need to create a custom field for published status. Use the Publish / Unpublish buttons in the dashboard, or the explicit POST /api/{collection}/{uuid}/publish and POST /api/{collection}/{uuid}/unpublish endpoints, to control whether an entry is live.

Draft / published and versions

NomaCMS uses a classic working-draft + published-snapshot model. Saving an entry never changes its publish state — it only updates the draft. Publishing is an explicit action that captures the current draft as an immutable JSON snapshot (v1, v2, v3, …).

  • API reads with state=published are served from the latest snapshot, so editing the draft does not leak to consumers until you publish again.
  • API reads with state=draft return live working-draft values.
  • Unpublishing clears the live pointer so state=published returns 404 — but versions are retained and still accessible via the versions endpoints.
  • You can revert to any prior version — NomaCMS restores the draft and publishes it as a new version (vNext), so history is never rewritten.

Version retention is plan-based: Basic 10, Grow 50, Pro unlimited. See Versions for the full lifecycle and API.

// A typical entry response
{
  uuid: "550e8400-e29b-41d4-a716-446655440000",
  locale: "en",
  state: "published",
  published_at: "2026-04-10T12:00:00Z",
  fields: {
    title: "Getting Started with NomaCMS",
    slug: "getting-started-with-noma",
    content: "<p>Welcome to NomaCMS...</p>"
  }
}

Assets

Assets are files uploaded to your project: images, documents, videos, audio. They live in the Asset Library and can be referenced from media fields in your entries.

Each asset has:

  • A unique UUID and ID
  • Original filename and MIME type
  • Public URL for serving to end users (no auth required)
  • Metadata like alt text, title, caption, description, author, and copyright

Assets support filtering by type (image, video, audio, document) and searching by filename.

Locales

NomaCMS supports multilingual content at the project level. You configure which locales your project supports (e.g. en, tr, es, de) and set a default locale.

Each entry belongs to a locale. Entries in different locales can be linked as translations of each other, creating a translation group. When you fetch an entry, you can request a specific locale or ask for its linked translation in another locale.

API keys

API keys authenticate requests to the Content API. You create them in User Settings → API Keys. Each key can have specific abilities that control what it can do:

AbilityWhat it allows
readList and get collections, entries, assets
createCreate entries, upload assets
updateUpdate entries, update asset metadata
deleteDelete entries, delete assets
adminManage collections, fields, webhooks, project locales

For most frontend applications, a key with read ability is all you need. Use admin for build tools, migration scripts, or AI integrations that manage schemas.

Project auth

Separate from API keys, project auth lets your end users sign up and sign in to your application. This is for the users of your product, not for CMS administrators.

Project auth provides:

  • Email/password sign up and sign in
  • Social login (Google, GitHub, etc. via id_token)
  • Session management with access and refresh tokens
  • User-scoped API keys for fine-grained access

Project auth is optional. You only enable it if your application has user accounts. See the Project Auth section for details.

What's next

Search documentation

Find guides and reference pages