Skip to main content

Schemas

Overview

Root CMS schemas are defined in .schema.ts files, which enables quicker iterative changes for developers while doing local development while preventing common errors with TypeScript's type-checking.

Creating CMS Collections

A collection is a way to logically organize your web app. Each doc in a collection shares a common schema.

To define a collection for usage in Root CMS, create a file at collections/<name>.schema.ts, for example:

ts
// @/collections/BlogPosts.schema.ts

import {schema} from '@blinkk/root-cms';

export default schema.collection({
  name: 'Blog Posts',
  description: 'The dopest blog.',
  url: '/blog/[slug]',
  preview: {
    title: 'meta.title',
    image: 'meta.image',
  },
  fields: [
    schema.string({
      id: 'title',
      label: 'Blog Title',
      translate: true,
    }),
    schema.image({
      id: 'image',
      label: 'Blog Image',
      help: 'Upload a 1600x900 JPG.',
    }),
    schema.richtext({
      id: 'content',
      label: 'Blog Content',
      translate: true,
    }),
  ],
});

Composing Schemas

Since schema files are .ts files, you can compose schemas by importing other schemas in your project. You can even use Vite's import.meta.glob to load all schema files within a folder. 

Example:

ts
import {schema} from '@blinkk/root-cms';

const templateModules = import.meta.glob('/templates/*/*.schema.ts', {
  eager: true,
});
const templates = Object.values(templateModules).map(
  (module: {default: schema.Schema}) => module.default
);

export default schema.collection({
  name: 'Pages',
  description: 'Landing Pages',
  url: '/[...slug]',
  preview: {
    title: 'meta.title',
    image: 'meta.image',
  },

  fields: [
    schema.object({
      id: 'meta',
      label: 'Meta',
      fields: [
        schema.string({
          id: 'title',
          label: 'Title',
          help: 'Page title.',
          translate: true,
        }),
        schema.string({
          id: 'description',
          label: 'Description',
          help: 'Description for SEO and social shares.',
          translate: true,
          variant: 'textarea',
        }),
        schema.image({
          id: 'image',
          label: 'Image',
          help: 'Meta image for social shares. Recommended: 1400x600 JPG.',
        }),
      ],
    }),

    schema.object({
      id: 'content',
      label: 'Content',
      fields: [
        schema.array({
          id: 'modules',
          label: 'Modules',
          help: 'Compose the page by adding one or more modules.',
          of: schema.oneOf({
            types: templates,
          }),
          preview: [
            'm{_index:02}: {description} (#{id})',
            'm{_index:02}: {title} (#{id})',
            'm{_index:02}: {description}',
            'm{_index:02}: {title}',
            'm{_index:02}: #{id}',
            'm{_index:02}: {_type}',
            'm{_index:02}',
          ],
        }),
      ],
    }),
  ],
});

In the example above, all schema files from templates/**/*.schema.ts are made available to the "content.modules" field, which allows developers to create template components that can be used to compose web pages.

Schema Field Types

For a list of all field types available to .schema.ts files, check out the source code on GitHub.

1
2
3
4
5
6
7
8
9
10
11
12
Breakpoint: