CMS 13 and 12 Graph comparison
CMS 13 introduces a unified, inheritance-based GraphQL schema for Optimizely Graph that changes how you query content, metadata, and referenced properties. Use this comparison to identify the query and output differences between Content Management System (CMS) 13 and CMS 12 and update your queries before upgrading.
This article covers the following areas:
- Content type structure differences.
- GraphQL schema differences.
- Property structure comparisons with query and response examples.
- Experience-based content queries.
- Content Graph feature comparison.
ImportantThe schema changes described in this article are breaking changes when you upgrade from CMS 12 to CMS 13. Review each section and update your queries before deploying.
Content type comparison
The following table compares content type support in CMS 12 and CMS 13.
| Content Type | CMS 12 | CMS 13 |
|---|---|---|
| PageType | Supported | Supported |
| BlockType | Supported | Supported |
| MediaType | Image, Video, GenericMedia | Image, Video, GenericMedia |
| Experience | Not supported | Supported |
| Section | Not supported | Supported |
GraphQL schema comparison
CMS 13 restructures the GraphQL schema to use a unified, inheritance-based model instead of the flat, per-type approach in CMS 12.
Both versions support standard GraphQL features, including queries with cursor, ids, limit, locale, skip, orderBy, pinned, where, facets, _fulltext, _and, _or, _not, _link, _children, _score, _json, _track, __modified, and _deleted.
The following list describes the key differences:
- CMS 12 exposes each content type as a separate root-level query.
- CMS 13 uses a unified, inheritance-based schema and adds support for
_metadata, Experiences, external sources, and Variations. - CMS 13 changes property query structures and output formats.
- CMS 13 removes support for
SiteIdandSiteDefinitionqueries. Use_metadata.url.baseto return content that belongs to a specific site.
CMS 13 defines base schema types (prefixed with _):
_Content, _Page, _Component, _Media, _Folder, _Experience, _Image, _Video, _Section, _Item, _AssetItem, _ImageItem.
Custom content types inherit from these base types. The following list describes examples of inheritance:
- A page type (
NewsPage) inherits from_Page. - A block type (
TeaserBlock) inherits from_Component. - Both
_Pageand_Componentinherit from_Content.
This inheritance model produces a consistent and extensible schema that enables uniform queries across content types.
Property query comparison
Use the following sections to understand how property queries differ between CMS 12 and CMS 13. Each section includes side-by-side queries and response examples.
Metadata properties
The following table compares equivalent metadata properties between CMS 12 and CMS 13. CMS 13 exposes metadata through the unified _metadata object, whereas CMS 12 exposes similar information through dedicated fields.
| CMS 12 | CMS 13 |
|---|---|
ContentLink { GuidValue } | _metadata { key } |
Language { Name } | _metadata { locale } |
ExistingLanguages { Name } | _metadata { locales } |
ContentLink { WorkId } | _metadata { version } |
ContentType | _metadata { types } |
Name | _metadata { displayName } |
StartPublish | _metadata { published } |
StopPublish | _metadata { expired } |
Status | _metadata { status } |
ParentLink { Id } | _metadata { container } |
Url | _metadata { url { base, default, graph, hierarchical, internal, type } } |
RouteSegment | _metadata { routeSegment } |
| Not available | _metadata { path } |
| Not available | _metadata { owner } |
| Not available | _metadata { ... on InstanceMetadata { expired } } |
| Not available | _metadata { ... on InstanceMetadata { lastModifiedBy } } |
| Not available | _metadata { ... on InstanceMetadata { createdBy } } |
Sample query comparison for metadata (IContentMetadata)
CMS 12 query:
query MyQuery {
Content(where: { Name: { eq: "Start2" } }) {
items {
ContentLink {
GuidValue
Id
WorkId
Url
}
Language {
Link
DisplayName
Name
}
Name
StartPublish
Status
Created
Changed
_sortOrder
ContentType
Url
}
}
}CMS 13 query:
query MyQuery {
_Content(where: { _metadata: { displayName: { eq: "Start2" } } }) {
items {
_metadata {
key
locale
version
displayName
published
status
changeset
created
lastModified
sortOrder
variation
types
url {
type
default
hierarchical
internal
graph
base
}
}
}
}
}CMS 12 result:
{
"data": {
"Content": {
"items": [
{
"ContentLink": {
"GuidValue": "337c7c36-1998-4a64-b3e1-ea4e544fdf76",
"Id": 1405,
"WorkId": 1704,
"Url": "https://localhost:8039/en/start2/"
},
"Language": {
"Link": "https://localhost:8039/en/start2/",
"DisplayName": "English",
"Name": "en"
},
"Name": "Start2",
"StartPublish": "2025-11-05T03:33:17Z",
"Status": "Published",
"Created": "2025-11-05T03:33:10Z",
"Changed": "2025-11-05T03:33:17Z",
"_sortOrder": 1700,
"ContentType": ["Page", "StartPage", "Content"],
"Url": "https://localhost:8039/en/start2/"
}
]
}
}
}CMS 13 result:
{
"data": {
"_Content": {
"items": [
{
"_metadata": {
"key": "f565ddf42213425390fdbad7147d2a06",
"locale": "en",
"version": "8",
"displayName": "Start2",
"published": "2025-11-24T04:14:09.698Z",
"status": "Published",
"changeset": "default",
"created": "2025-11-24T04:13:53.504Z",
"lastModified": "2025-11-24T04:14:09.698Z",
"sortOrder": 0,
"variation": null,
"types": ["StartPage", "_Page", "_Content", "_Item"],
"url": {
"type": "HIERARCHICAL",
"default": "/en/start2/",
"hierarchical": "/en/start2/",
"internal": "cms://content/f565ddf42213425390fdbad7147d2a06?loc=en&ver=8",
"graph": "graph://cms/StartPage/f565ddf42213425390fdbad7147d2a06",
"base": "https://localhost:8001"
}
}
}
]
}
}
}CMS 13 removes support for SiteId and SiteDefinition queries. Scope queries to a site by filtering on _metadata.url.base to return content that belongs to the specified hostname.
The following query demonstrates site-scoped filtering:
query {
_Content(
where: {
_metadata: {
url: {
base: { eq: "https://site-a.com" }
}
}
}
) {
items {
_id
_metadata {
url {
base
}
}
}
}
}CMS 13 structures metadata into different scopes to separate content lifecycle, content identity, and media-specific information.
InstanceMetadata
Use InstanceMetadata when you query standalone content instances such as pages and blocks. Cast _metadata to InstanceMetadata to access instance-level details that extend IContentMetadata with the following properties:
container– The key of the content item that contains this item.owner– The key of the owning content item when the content is an asset of another content item.path– The hierarchy of containers for this item.
InstanceMetadata query example:
query MyQuery {
_Content(where: { _metadata: { displayName: { eq: "Start2" } } }) {
items {
_metadata {
displayName
... on InstanceMetadata {
routeSegment
container
createdBy
expired
lastModifiedBy
locales
owner
path
}
}
}
}
}InstanceMetadata result:
{
"data": {
"_Content": {
"items": [
{
"_metadata": {
"displayName": "Start2",
"routeSegment": "start2",
"container": "dd3adb7ae0884449a1eed6c7f1dffdef",
"createdBy": "[email protected]",
"expired": null,
"lastModifiedBy": "[email protected]",
"locales": ["en"],
"owner": null,
"path": [
"dd3adb7ae0884449a1eed6c7f1dffdef",
"f565ddf42213425390fdbad7147d2a06"
]
}
}
]
}
}
}ItemMetadata
Use ItemMetadata for content items that appear inside a container, such as entries in a ContentArea. Cast _metadata to ItemMetadata to access properties such as displayOption that extend IContentMetadata.
ItemMetadata query example:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage3" } } }) {
items {
_metadata {
displayName
key
}
ContentArea {
_metadata {
... on ItemMetadata {
displayOption
locale
key
}
}
}
}
}
}ItemMetadata result:
{
"data": {
"StandardPage": {
"items": [
{
"_metadata": {
"displayName": "StandardPage3",
"key": "0076eb95f7e0425ea082197d2bb039a8"
},
"ContentArea": [
{
"_metadata": {
"displayOption": null,
"locale": "en",
"key": "f565ddf42213425390fdbad7147d2a06"
}
},
{
"_metadata": {
"displayOption": null,
"locale": "en",
"key": "b8a60749ef584cedbaf111a4f93ae15d"
}
}
]
}
]
}
}
}MediaMetadata
Use MediaMetadata for media content such as images, videos, and other media files. Cast _metadata to MediaMetadata to access properties such as container, mimeType, and thumbnail that extend IContentMetadata.
MediaMetadata query example:
query MyQuery {
_Content(where: { _metadata: { displayName: { eq: "Image1.png" } } }) {
items {
_metadata {
displayName
... on MediaMetadata {
container
content
createdBy
expired
lastModifiedBy
locales
mimeType
owner
path
routeSegment
thumbnail
}
}
}
}
}MediaMetadata result:
{
"data": {
"_Content": {
"items": [
{
"_metadata": {
"displayName": "Image1.png",
"container": "e56f85d0e8334e02976a2d11fe4d598c",
"content": "A beautiful picture",
"createdBy": "[email protected]",
"expired": null,
"lastModifiedBy": "[email protected]",
"locales": [],
"mimeType": "image/png",
"owner": null,
"path": ["aabdb22fd36c4044af0b14cc31efb292"],
"routeSegment": "Image1",
"thumbnail": "https://app-sactmain242x8byp001.cmstest.optimizely.com/globalassets/Image1//thumbnail"
}
}
]
}
}
}Standard primitive properties
Standard primitive property types such as String, Int, Boolean, DateTime, Float, Guid, and Choice use the same query syntax and return responses in a consistent format across both versions.
CMS 12 query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage3" } }) {
items {
p_String
p_Select
p_Int
p_Guid
p_Date
p_Choice
}
}
}CMS 13 query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage3" } } }) {
items {
p_String
p_Select
p_Int
p_Guid
p_Date
p_Choice
}
}
}Both versions return similar result structures. The primary difference is in how the where filter references content (by Name in CMS 12 versus _metadata.displayName in CMS 13).
Query referenced properties
CMS 13 changes how you query referenced content. In CMS 12, you expand referenced content through ContentArea, ContentAreaItem, ContentReference, LinkItem, LinkItemCollection, and similar properties. In CMS 13, you query referenced content only through ContentArea or ContentAreaItem. Other property types such as ContentReference, PageReference, and LinkItem return link information only.
ContentArea or ContentAreaItem properties
In CMS 12, ContentArea items are queried through ContentLink.Expanded, which returns the referenced data. CMS 13 removes this expansion model. Query referenced content explicitly through inline fragments or fragments instead.
CMS 12 query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage1" } }) {
total
items {
MainContentArea {
InlineBlock {
ContentType
}
DisplayOption
ContentLink {
GuidValue
Id
ProviderName
Url
WorkId
Expanded {
... on ButtonBlock {
Name
Created
Url
ButtonText
}
}
}
}
}
}
}CMS 13 query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
total
items {
MainContentArea {
... on ButtonBlock {
_metadata {
key
locale
fallbackForLocale
version
displayName
published
status
changeset
created
lastModified
sortOrder
variation
types
url {
type
default
hierarchical
internal
graph
base
}
}
ButtonText
}
}
}
}
}The following query retrieves a ContentArea with multiple block types through inline fragments:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage2" } } }) {
total
items {
MainContentArea {
... on ButtonBlock {
_metadata {
version
created
key
}
ButtonText
}
... on EditorialBlock {
_metadata {
displayName
key
}
_id
}
... on TeaserBlock {
_metadata {
displayName
key
}
Text
}
}
}
}
}The following query retrieves a ContentArea with multiple block types through named fragments:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage2" } } }) {
total
items {
MainContentArea {
_metadata {
displayName
key
}
...ButtonBlockFragment
...EditorialBlockFragment
...TeaserBlockFragment
}
}
}
}
fragment ButtonBlockFragment on ButtonBlock {
_metadata {
version
}
ButtonText
}
fragment EditorialBlockFragment on EditorialBlock {
_id
}
fragment TeaserBlockFragment on TeaserBlock {
Text
}Recursive queries on ContentArea
In CMS 12, the @recursive directive applies to ContentArea.ContentLink.Expanded with a default maximum depth of three levels. CMS 13 removes the Expanded field and applies recursion directly to the ContentArea property through the @recursive directive, typically inside a fragment. This approach provides cleaner queries and more reliable access to nested or cyclic ContentArea structures.
CMS 12 recursive query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage1" } }) {
items {
ContentArea {
ContentLink {
Expanded {
Name
...ContentAreaBlock
}
}
}
}
}
}
fragment ContentAreaBlock on ContentAreaBlock {
Name
ContentType
ContentArea {
ContentLink {
Expanded @recursive(depth: 10) {
Name
ContentType
}
}
}
}CMS 13 recursive query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
items {
MainContentArea {
_metadata {
displayName
}
...ContentAreaBlock
}
}
}
}
fragment ContentAreaBlock on ContentAreaBlock {
_metadata {
displayName
types
}
cultureContentArea @recursive(depth: 10) {
_metadata {
displayName
}
}
}ContentReference and ContentReferenceList properties
In CMS 12, ContentReference and ContentReferenceList properties expand and return the referenced content through the Expanded field. In CMS 13, these properties return a structured url object and a stable key. Query the referenced content explicitly when needed.
CMS 12 query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage1" } }) {
total
items {
ContentReference {
GuidValue
Id
Url
WorkId
Expanded {
Url
ContentLink {
Id
GuidValue
Url
WorkId
}
}
}
}
}
}CMS 13 query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
total
items {
ContentReference {
url {
type
default
hierarchical
internal
graph
base
}
key
}
}
}
}In CMS 13, ContentReference and ContentReferenceList properties reference content from external sources and CMS-managed content. Retrieve external items through the ContentReference.item field for unified querying of internal and external content.
External content reference query example:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
total
items {
ContentReference {
url {
type
default
hierarchical
internal
graph
base
}
key
item {
_id
... on GraphShadowType {
Name
Id
_id
_modified
}
}
}
}
}
}External content reference result:
{
"data": {
"StandardPage": {
"total": 1,
"items": [
{
"ContentReference": {
"url": {
"type": "GRAPH",
"default": null,
"hierarchical": null,
"internal": "cms://content/43fd8aecaad245d3b59b0db48c615cdb",
"graph": "graph://shadow/GraphShadowType/101",
"base": null
},
"key": "43fd8aecaad245d3b59b0db48c615cdb",
"item": {
"_id": "2",
"Name": "Shakespeare",
"Id": 101,
"_modified": "2025-12-12T06:52:21Z"
}
}
}
]
}
}
}LinkItem, LinkItemList, and LinkItemCollection properties
In CMS 12, link data is retrieved through Href and ContentLink with expanded content details. CMS 13 simplifies the model by exposing a unified url object with structured URL types. The LinkItem, LinkItemList, and LinkItemCollection properties no longer expand referenced content.
CMS 12 query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage1" } }) {
total
items {
LinkItem {
Title
Text
Target
Href
ContentLink {
Id
WorkId
GuidValue
Url
Expanded {
Name
Created
}
}
}
}
}
}CMS 13 query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
total
items {
LinkItem {
title
text
target
url {
type
default
hierarchical
internal
graph
base
}
}
}
}
}Url and UrlList properties
In CMS 12, Url and UrlList properties return plain string values. In CMS 13, these properties return structured objects with multiple representations. The Graph schema for Url includes the following fields:
default– The default URL for the content instance.type– The type for thedefaultvalue. Possible values includeHIERARCHICAL,INTERNAL,EXTERNAL, and others.hierarchical– The path for the content item based on the hierarchical structure in CMS 13.internal– A permanent URL to the content item. The integration API uses this format to reference content items.base– The authority for the content item. This value depends on the application configuration in CMS 13.
CMS 12 query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage1" } }) {
total
items {
UrlToImage
}
}
}CMS 13 query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
total
items {
UrlToImage {
type
default
hierarchical
internal
graph
base
}
}
}
}XhtmlString and XhtmlStringList properties
In CMS 12, XhtmlString and XhtmlStringList properties return raw HTML as a plain string. CMS 13 returns rich text as a structured object that includes rendered HTML and a JSON representation. This structure enables more flexible rendering and content processing on the front end. The XhtmlString property returns the following fields by default:
html– The rendered HTML string.json– A structured representation of the rich text.
The json value follows a tree structure:
- The root node has
type: "richText"and achildrenarray. - Each child node has a
type(for example,paragraph) and its ownchildren.
CMS 12 query:
query MyQuery {
StandardPage(where: { Name: { eq: "StandardPage1" } }) {
items {
XhtmlString
}
}
}CMS 13 query:
query MyQuery {
StandardPage(where: { _metadata: { displayName: { eq: "StandardPage1" } } }) {
items {
XhtmlString {
html
json
}
}
}
}CMS 12 result:
{
"data": {
"StandardPage": {
"items": [
{
"XhtmlString": "<p>Apple is red!</p>"
}
]
}
}
}CMS 13 result:
{
"data": {
"StandardPage": {
"items": [
{
"XhtmlString": {
"html": "<p>Apple is red!</p>",
"json": {
"type": "richText",
"children": [
{
"type": "paragraph",
"children": [
{
"text": "Apple is red!"
}
]
}
]
}
}
}
]
}
}
}Experience query on CMS 13
Visual Builder in CMS 13 introduces a layout-and-composition-based approach to content creation that uses small, reusable content units. Use Experience queries to retrieve structured layout data for front-end rendering.
An Experience functions like a Page but supports layouts and unstructured editor-added content. Experiences organize content as an ordered list of Sections. Sections and Elements extend Blocks. Sections act as layout containers, while Elements represent the smallest content units and contain the actual content data. Elements are leaf nodes in the composition tree with no child elements.
The following query retrieves data for Experiences, Sections, and Elements. An Experience contains a composition field with a tree of nodes. CompositionStructureNode represents layout containers (Sections). CompositionComponentNode represents content units (Elements). Structure nodes contain other nodes, and component nodes are leaf nodes.
fragment _IComponent on _IComponent {
__typename
... on BlankSection {
longString
string
xhtmlString {
html
}
Int
contentArea {
_metadata {
key
displayName
}
... on _Content {
_metadata {
created
version
}
}
}
contentReference {
key
url {
default
base
}
}
block {
Description
}
}
... on ContentAreaBlock {
_metadata {
displayName
types
}
Link {
Heading
Text
}
}
}
fragment ElementFields on Element {
Name
Time
Number
}
fragment _IExperience on _IExperience {
composition {
...ICompositionNode
}
}
fragment ICompositionNode on ICompositionNode {
... on CompositionStructureNode {
key
displayName
nodeType
layoutType
component {
..._IComponent
}
nodes @recursive {
type
nodeType
layoutType
displayName
key
displayTemplateKey
}
}
... on CompositionComponentNode {
key
displayName
nodeType
component {
..._IComponent
...ElementFields
}
}
}
fragment BlankExperience on BlankExperience {
..._IExperience
}
query MyQuery {
_Content(where: { _metadata: { displayName: { contains: "BlankExper236" } } }) {
item {
__typename
_metadata {
displayName
version
}
...BlankExperience
}
}
}Variation query on CMS 13
CMS 13 lets editors create one or more variations of a page or an experience. A unique string in the variation field on the content metadata identifies each variation. By default, GraphQL queries return the original (non-variation) content only. Use the variation filter to query specific variations or retrieve all variations.
The following query retrieves all variations of a content item:
query GetAllVariations {
_Content(variation: { include: ALL, includeOriginal: true }) {
items {
_metadata {
key
displayName
}
}
}
}The following query retrieves specific variations:
query variation {
_Content(
where: { _metadata: { displayName: { eq: "Rainrain" } } }
variation: { includeOriginal: false, include: SOME, value: "Variation_2" }
) {
items {
_metadata {
variation
displayName
}
}
}
}The following query retrieves default content only (no variations):
query GetOnlyDefaultContent {
_Content(variation: { include: NONE, includeOriginal: true }) {
items {
_metadata {
displayName
variation
}
}
}
}Optimizely Graph features
Core Content Graph features such as _children, _link, full-text search, filtering through search providers, and fuzzy search remain functionally consistent between CMS 12 and CMS 13. CMS 13 retains these capabilities and introduces a more normalized and composable schema. Update your query structure, not your feature logic.
Summary of key differences
CMS 13 introduces structural improvements through Optimizely Graph and the Experience model that change how you query content compared to CMS 12. The following list summarizes the key differences:
- URLs return as structured objects instead of plain strings.
XhtmlStringexposes both HTML and JSON representations by default.ContentArea,ContentAreaItem,ContentReference, and Link properties no longer supportExpand. Query referenced content explicitly.- All blocks are queryable through the unified
_Componentinterface. - Queries use
_Contentand_Mediaas root fields instead ofContentand individual media types. - CMS 13 adds support for
_metadata, Experiences, external sources, and Variations.
Updated 13 days ago
