Model content types
Define and structure CMS content types in code, including properties, relationships, and search behavior, and sync them to Optimizely CMS (SaaS).
Model content types for Optimizely CMS using the Optimizely JavaScript SDK. You define content types in code, configure their properties, relationships, and search behavior, and then sync them to the CMS using the CLI.
Use this approach to keep your content model versioned, reusable, and aligned with your application code.
Prerequisites
- You have installed the Optimizely JavaScript SDK. See Install JavaScript SDK.
- You have configured the Optimizely CMS CLI and connected it to your CMS instance. See Configure JavaScript SDK.
- Your project uses a supported JavaScript or TypeScript configuration (for example, Next.js).
Define a content type
Create a file in your components directory to define a content type. The following example defines an Article page type:
import { contentType } from "@optimizely/cms-sdk";
export const ArticleContentType = contentType({
key: "Article",
baseType: "_page",
properties: {
heading: {
type: "string",
displayName: "Article Heading",
group: "content",
indexingType: "searchable",
},
body: {
type: "richText",
displayName: "Article Body",
group: "content",
},
},
});This example demonstrates a basic page (_page) content type with the following common property types:
- string – For short, unformatted text such as titles or labels.
- richText – For formatted content that supports rich text editing, such as article bodies.
These property types form the foundation of most content models.
Property configuration
Each property supports a set of configuration options that control how it displays in the CMS (SaaS) editor, how the system validates it, and how the system indexes it for search.
Property types
The type field defines the data type of a property. Supported types include the following:
string– Simple text.richText– Formatted content (Slate.js format).boolean– True or false.integer– Whole numbers.float– Decimal numbers.dateTime– Date and time values.url– Simple URLs.link– Links with metadata.binary– Binary files.json– Structured JSON.content– References to other content.contentReference– References with constraints.array– Lists of values.component– Embedded components.
URL property
Use the url type to store a simple web address as a string.
properties: {
websiteUrl: {
type: 'url',
displayName: 'Website URL',
description: 'External website link',
},
}Link property
Use the link type when you need additional metadata such as link text, title, or target.
properties: {
ctaLink: {
type: 'link',
displayName: 'Call to Action Link',
description: 'Link with title and target options',
},
}Use url for simple storage. Use link when you need full anchor tag behavior.
Date and time properties
Use the dateTime type to store dates or timestamps. You can optionally enforce minimum and maximum values.
properties: {
publishDate: {
type: 'dateTime',
displayName: 'Publish Date',
required: true,
},
eventStartTime: {
type: 'dateTime',
displayName: 'Event Start',
minimum: '2025-12-01T00:00:00Z',
maximum: '2025-12-31T23:59:59Z',
},
}Both minimum and maximum accept ISO 8601 date-time strings.
Array properties
Use the array type to store lists of values. Define the item type using the items field.
properties: {
tags: {
type: 'array',
items: { type: 'string' },
displayName: 'Tags',
minItems: 1,
maxItems: 10,
},
relatedArticles: {
type: 'array',
items: {
type: 'content',
allowedTypes: [ArticleContentType],
},
displayName: 'Related Articles',
},
}Array properties support the following:
minItems– Minimum number of items.maxItems– Maximum number of items.- All item types except nested arrays.
Component properties
Use the component type to embed a specific component (block) directly in another content type.
const HeroComponentType = contentType({
key: "Hero",
baseType: "_component",
properties: {
title: { type: "string" },
image: { type: "contentReference", allowedTypes: ["_image"] },
},
});
const LandingPageType = contentType({
key: "LandingPage",
baseType: "_page",
properties: {
hero: {
type: "component",
contentType: HeroComponentType,
displayName: "Hero Section",
},
},
});The contentType field specifies which component type the property allows.
Indexing types
The indexingType field controls how a property participates in search.
searchable(default) – Full-text search.queryable– Filtering and sorting only.disabled– Not indexed.
properties: {
title: {
type: 'string',
indexingType: 'searchable',
},
publishDate: {
type: 'dateTime',
indexingType: 'queryable',
},
internalNotes: {
type: 'string',
indexingType: 'disabled',
},
}
Content relationships
Use allowedTypes and restrictedTypes to control which content types a reference property can select.
const BlogPageContentType = contentType({
key: "BlogPage",
baseType: "_page",
properties: {
featuredArticle: {
type: "content",
allowedTypes: [ArticleContentType],
displayName: "Featured Article",
},
relatedContent: {
type: "content",
restrictedTypes: ["_folder"],
displayName: "Related Content",
},
},
});Supported values
Note from Trisha during peer reviewI'm not really sure what the following list means? Can you maybe rewrite it using parallel structure? I think you mean something like this (but I'm not 100% sure, so I don't want to change it):
Specific content types include the following:
- Base types, such as
_pageand_component.- The
_selfkeyword for self-referencing.- A specific keyword or value to allow all content types.
Specific content types
- User defined content types where base types are (
_page,_experience) _selffor self-referencing.*to allow all types.
Container rules with mayContainTypes
mayContainTypesUse mayContainTypes to define which content types a container can hold.
const BlogPageContentType = contentType({
key: "BlogPage",
baseType: "_page",
mayContainTypes: [ArticleContentType, "_self"],
});This applies to _page and _experience base types and helps enforce structured content hierarchies.
Sync content types to the CMS
After defining your content types, push them to CMS (SaaS) using the CLI.
npx @optimizely/cms-cli@latest config push optimizely.config.mjsCMS (SaaS) creates or updates the corresponding content types based on your configuration.
Next steps
You can now create content in CMS (SaaS) using the modeled content types and fetch it through the Optimizely API or SDK.
Updated 1 day ago
