Shadow Content Types
Outline
- Virtual representation: Shadow types act as metadata-only pointers to external data in Optimizely Graph, eliminating physical database replication.
- Schema-first modeling: Integration starts with GraphQL introspection rather than C# classes, allowing for automated property generation and recursive shadowing.
- Sync efficiency: These types are explicitly excluded from the CMS-to-Graph sync to prevent circular indexing loops and maintain high performance.
- Unified discovery: Editors can search and link to external assets (DAM, PIM) directly within the CMS UI as if they were native content.
In the architectural journey of modern digital experience platforms, Optimizely CMS 13 represents a profound departure from the monolithic constraints of the past. The definition of "content" is no longer confined to the rows and columns of a local SQL database. As enterprise ecosystems become increasingly fragmented into composable stacks—integrating Digital Asset Management (DAM), Product Information Management (PIM), and external CRM data—the traditional model of data duplication creates unsustainable technical friction. Optimizely CMS 13 introduces Shadow Content Types as the primary solution to this friction. In a "Graph-first" ecosystem, shadow content types act as virtual representatives of data that lives elsewhere, allowing the CMS to serve as a unified orchestration layer where external data is "shadowed" into the CMS interface without the burden of physical replication.
What are Shadow Content Types?
Technically, a shadow content type is a metadata-only content definition registered within the CMS that maps directly to a schema in Optimizely Graph. Unlike a standard Page or Block type defined in C# code, a shadow type does not possess a corresponding table entry for its properties in the CMS primary database (tblContent). Instead, it is a "pass-through" entity designed to provide the CMS UI with the information it needs to display and relate to external items.
Key Technical Characteristics:
-
Naming Convention: To prevent namespace collisions, shadow types are automatically prefixed with
graph:(e.g.,graph:cmp_PublicImageAsset). - Read-Only Nature: Because the CMS is not the authority for this data, shadow types are strictly read-only. Editors can "select" an item or link to it, but they cannot modify the fields of a shadow object within the CMS Edit View.
- Metadata Attribution: Every shadow object carries a source attribute identifying its origin system, such as Bynder, Salesforce, or a custom API.
Why Shadow Content Types Exist: Solving the Duplication Crisis
The primary driver for the existence of shadow content types is the elimination of Synchronization Bloat. Historically, developers were forced to choose between two suboptimal patterns when integrating external data into a CMS.
1. The Import/Duplication Pattern
In this model, developers wrote scheduled jobs to "import" external records as CMS blocks. This inevitably led to "data drifting"—where a PIM updated a product price, but the CMS block continued to show the old price until the next sync cycle. Furthermore, this bloated the CMS database with thousands of duplicate records, making backups, migrations, and searches increasingly heavy and inefficient.
2. The Custom Content Provider Pattern
Alternatively, developers would implement a custom ContentProvider. While this avoided database duplication, it often paralyzed the editor experience. Every time an editor opened a selection tree or search box, the CMS server had to make real-time, blocking API calls to the external system. This created latency, timeouts, and a sluggish interface that frustrated content teams.
Shadow Content Types solve both problems simultaneously. By ensuring all external data is ingested into the high-performance Optimizely Graph index first, the CMS can query that data with sub-second latency. The "Shadow" in the CMS is essentially a portal to that index, providing the performance of a local database without the maintenance cost of data migration.
Influencing the Modeling Process: A Schema-First Workflow
Modeling in CMS 13 requires a fundamental shift in developer mindset. Instead of starting with a C# class, the modeling process now begins with Schema Introspection.
Automated Schema Discovery
When an external source is connected via the Optimizely Connect Platform (OCP), the CMS introspects the GraphQL schema of that source. It automatically identifies fields and generates corresponding properties for the shadow type. If the external source provides a String field titled AssetDescription, the CMS creates a matching read-only PropertyLongString definition.
Recursive Shadowing and Type Hierarchies
Enterprises rarely have flat data structures. If an external record contains a nested complex object (e.g., a "Product" containing a "Warranty" object), the CMS 13 engine can recursively generate a secondary shadow content type for that nested entity. This ensures that the structured hierarchy of the enterprise data is preserved and navigable within the CMS, allowing for sophisticated multi-level relationships.
Base Type Mapping
Developers can influence how the CMS treats these shadow types by mapping them to Base Types. By telling Optimizely that a shadow record should be treated as an Image base type, the system automatically enables native thumbnail generation, drag-and-drop support in media zones, and dedicated media pickers. This allows external assets to feel completely native to the editor.
Impact on the Indexing Pipeline: The Filtered Sync Flow
The indexing strategy for shadow content types is designed to prevent "circular indexing logic." To understand this, we must examine the CMS-to-Graph Synchronization pipeline.
In a standard flow, when an editor saves a native page, the CMS Sync package detects the update and pushes the new data into Optimizely Graph. However, if the CMS treated shadow content the same way, it would create an infinite loop: the data would flow from an external PIM into Graph, the CMS would "shadow" it, and then try to push it back to Graph as if it were local content.
Shadow Content Types are explicitly excluded from the CMS-to-Graph sync. They are considered "index-resident" by default. This ensures that Optimizely Graph remains the sole, clean source of truth for external data, while the CMS maintains a light reference layer. This "Read-Only/No-Sync" rule is critical for maintaining high performance in large-scale environments with millions of external assets.
Unified Discovery: The Editor Experience
For the end-user (the editor), shadow content types enable Unified Discovery. Within the new Content Manager, editors no longer need to switch contexts or tabs to find what they need. They can perform a single search for a keyword and see a unified result list containing:
- Internal Content: Native CMS Pages and Blocks.
- Asset Management: CMP or Bynder images (via shadow types).
- Product Data: PIM items or CRM leads (via shadow types).
This allows developers to build "Smart Pickers"—properties on a native Page that allow an editor to browse a virtual folder of thousands of product items without ever having to import a single one of them into the CMS SQL database.
Conclusion
Shadow content types represent the maturity of the Optimizely platform as a truly composable orchestrator. By shifting from physical data duplication to a virtualized, Graph-first architecture, developers can build lighter and more performant systems. This paradigm shift allows the CMS to act as a unified interface for the entire enterprise stack, ensuring that if data is indexed in Graph, it is immediately available for editorial use without the overhead of traditional migration.
