Skip to content

Schema

The schema is an object that maps names to Types. Pass it to createCMS as the schema option: every type an editor can create as an entry has to be listed here.

schema.ts
import {Config, Field} from 'alinea'

export const Blog = Config.document('Blog', {
  contains: ['BlogPost'],
  fields: {}
})

export const BlogPost = Config.document('Blog post', {
  fields: {
    publishDate: Field.date('Publish date'),
    body: Field.richText('Body')
  }
})
cms.ts
import {Config} from 'alinea'
import {createCMS} from 'alinea/next'
import * as schema from './schema'

export const cms = createCMS({
  schema,
  workspaces: {
    main: Config.workspace('Blog', {
      source: 'content',
      roots: {pages: Config.root('Pages', {contains: ['Blog']})}
    })
  },
  handlerUrl: '/api/cms'
})

In this example Blog is a container that accepts BlogPost children, so editors create an overview page and add posts below it.

Type names

The key of a type in the schema is its name. It's written to the _type property of every entry file and it's the name you use in contains, in link conditions ({_type: 'BlogPost'}) and in query results (Query.type). The label you pass to Config.document or Config.type is only shown in the dashboard.

  • Names must start with a letter and contain only letters, digits and underscores. Entry, MediaFile and MediaLibrary are reserved: Alinea adds the last two for uploads and media folders.

  • Renaming a key renames the type: existing entries that still carry the old name fail to load with "has an unknown type". Rename the _type in those files at the same time.

  • Every name used in contains must exist in the schema, otherwise alinea dev stops with an error that names the missing type.

Organizing a larger schema

Exporting every type from one module and importing it with import * as schema keeps the config short. In larger projects it's common to keep each type next to the component that renders it and collect them in one place:

schema.ts
export {Article} from './pages/article/Article.schema'
export {Home} from './pages/home/Home.schema'
export {Settings} from './pages/settings/Settings.schema'

Types that are only used as blocks inside a List or Rich text field don't need to be in the schema: they're registered by the field that uses them.

Good to know

  • A type can appear only once in the schema, and a field instance can belong to only one type. Registering either twice throws "is already in use", see Fields must be unique.

  • Config.schema({types: {...}}) is available as a helper, but it returns the types object as is: a plain object works the same.

In this section