@cmssy/types
One dependency-free package describing blocks, fields, pages, models, forms and commerce - shared by the SDK, the platform and your app.
Every part of cmssy - the platform, the SDK, the AI tools, your app - has to agree on what a block is, what a field is, what a page looks like. @cmssy/types is where that agreement is written down.
It contains types and a handful of pure helpers. No runtime dependency, no framework, nothing to bundle.
You usually get it for free
You rarely install it yourself. @cmssy/react and @cmssy/next re-export what you need, so a normal app never imports it directly.
Reach for it when you are writing something that sits beside the SDK: a script that reads block content, a migration, a custom dashboard, an editor integration. Then you want the vocabulary without pulling in React.
What is in it
- Fields -
FieldTypeand the field-type value lists,FieldValidation,ValidationPattern(email,url,phone,slug), and the conditional-display types. - Block schema -
FieldDefinition,BlockSchema,BlockPropsSchema,BlockMeta, plusInferBlockContent, which derives a block's content type from its props schema. - Content -
CmssyPageData,CmssyPageSummary,CmssyPageMeta,RawBlock,RawLayoutBlock,CmssyLocalizedValue,CmssySiteConfig,CmssyBranding,CmssySiteLocales. - Models -
CmssyModelDefinition,CmssyModelRecord,CmssyRecordList. - Layout, forms, commerce, integrations, modules, templates - one file each.
Two helpers worth knowing
isLocalizableFieldType(type) answers whether a field type carries per-language values. Not every type does - a boolean or a colour is the same in every language, and treating it as translatable produces five copies of one value.
evaluateFieldConditionGroup(...) evaluates conditional field visibility. It is a pure function rather than editor-internal logic, so a custom UI can decide which fields to show using exactly the rules the cmssy editor uses. Two implementations of "show this field when..." would drift, and the drift would show up as a field that is required but invisible.
Localized values are a union
The type that surprises people:
type CmssyLocalizedValue = Record<string, string> | string | null;A localized value is a language map or a bare string or null. The bare string is legacy content written before the field was localized, and it is still valid - so narrow before you index:
const title =
typeof value === "string" ? value : (value?.[locale] ?? value?.[defaultLocale] ?? "");Reaching straight for value[locale] works until it meets an older field, and then it silently yields undefined.
Next steps
- Block schema & field types - the field types these describe.
- GraphQL delivery API - where
RawBlockandCmssyPageDatacome from. - i18n - the fallback chain for localized values.