Why set up Graph
Section titled “Why set up Graph”Graph turns your CMS into a headless content API. Once connected, any frontend — React, Next.js, Vue, mobile app — can query your content via GraphQL. This guide walks you through the setup from configuration to first query.
Read Content Delivery with Graph first to understand the architecture and decide if headless delivery fits your needs.
Step 1: Install the Graph package
Section titled “Step 1: Install the Graph package”dotnet add package Optimizely.ContentGraph.Cms Step 2: Configure Graph credentials
Section titled “Step 2: Configure Graph credentials”Add your Graph credentials to the application settings. You can find these in the Optimizely portal under your Graph subscription.
{
"Optimizely": {
"ContentGraph": {
"GatewayAddress": "https://cg.optimizely.com",
"AppKey": "your-app-key",
"Secret": "your-secret-key",
"SingleKey": "your-single-key",
"AllowSendingLog": true
}
}
} Keys explained:
- AppKey — Identifies your Graph instance
- Secret — Used for HMAC authentication (server-to-server)
- SingleKey — Used for simple authentication (public frontends)
Step 3: Register Graph in the service collection
Section titled “Step 3: Register Graph in the service collection”var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddCmsAspNetIdentity<ApplicationUser>()
.AddCms()
.AddContentGraph(builder.Configuration); // Add this line
var app = builder.Build(); Step 4: Sync content to Graph
Section titled “Step 4: Sync content to Graph”Content syncs automatically when published. To trigger a full sync of all existing content:
# Via the CMS admin interface:
# Navigate to CMS Admin → Scheduled Jobs → "Content Graph Content Synchronization"
# Click "Start Manually"
# Or via the Graph admin API:
curl -X POST https://cg.optimizely.com/api/content/v3/sync \
-H "Authorization: Basic {base64(AppKey:Secret)}" The initial sync may take several minutes depending on content volume. Subsequent publishes sync incrementally in near real-time.
Step 5: Explore the GraphQL playground
Section titled “Step 5: Explore the GraphQL playground”Graph provides an interactive playground where you can explore your schema and test queries.
- Navigate to
https://cg.optimizely.com/content/v2?auth={SingleKey} - The playground shows your full schema on the left
- Every CMS content type appears as a GraphQL type
- Write and execute queries interactively
Step 6: Write your first query
Section titled “Step 6: Write your first query”# Get all published article pages
query GetArticles {
ArticlePage(
where: { _metadata: { status: { eq: "Published" } } }
orderBy: { _metadata: { published: DESC } }
limit: 10
) {
items {
Headline
Author
ArticleBody {
html
}
_metadata {
published
url {
default
}
}
}
total
}
} const GRAPH_URL = 'https://cg.optimizely.com/content/v2';
const SINGLE_KEY = process.env.GRAPH_SINGLE_KEY;
async function getArticles() {
const response = await fetch(GRAPH_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${SINGLE_KEY}`,
},
body: JSON.stringify({
query: `query {
ArticlePage(limit: 10) {
items { Headline Author }
}
}`
})
});
return response.json();
} using Optimizely.ContentGraph.Cms;
public class ArticleService
{
private readonly IContentGraphClient _client;
public ArticleService(IContentGraphClient client)
{
_client = client;
}
public async Task<IEnumerable<ArticlePage>> GetLatest()
{
var result = await _client
.ForType<ArticlePage>()
.OrderBy(x => x.PublishedDate, OrderBy.DESC)
.Limit(10)
.GetResultAsync();
return result.Items;
}
} Verify the setup
Section titled “Verify the setup”After completing these steps, verify:
- Content appears in GraphQL playground — Run the query from Step 6
- Real-time sync works — Publish a new page in CMS, then query Graph — it should appear within seconds
- Authentication works — Test with both SingleKey (for public queries) and HMAC (for server-side)
Troubleshooting
Section titled “Troubleshooting”| Issue | Likely cause | Fix |
|---|---|---|
| No types in schema | Content not synced | Run the full sync job in CMS Admin |
| 401 Unauthorized | Invalid credentials | Verify AppKey/Secret/SingleKey in config |
| Published content missing | Sync delay or filter | Wait 30 seconds, or check content status is Published |
| Custom properties missing | Type not indexed | Ensure content type has [ContentType] attribute |