Personalization
Adapt documentation to each signed-in reader with safe server-rendered MDX expressions and personalized API examples.
Personalize One Build For Every Reader
Personalization is a work in progress. The preview workflow is available for evaluation, but the user-data contract and production authentication behavior may change before the feature is generally available. Do not rely on it for production access control yet.
Relevate can adapt a page after authentication without creating a separate docs build for every customer. Write conditions against user, and Relevate selects the matching precompiled content on the server.
Welcome back, {user.firstName}.
{user.plan === 'enterprise'
? <Tip>Enterprise features are enabled for {user.organization.name}.</Tip>
: <Note>Upgrade to unlock enterprise features.</Note>}
Public pages continue to use the normal shared cache. Pages containing personalization are returned privately with Cache-Control: private, no-store and Vary: Cookie.
User Data
Authenticated user data uses this shape:
{
"groups": ["admin", "enterprise"],
"content": {
"firstName": "Jane",
"plan": "enterprise",
"role": "admin",
"organization": {
"name": "Acme",
"region": "eu-west"
}
},
"apiPlaygroundInputs": {
"header": {
"Authorization": "Bearer user_abc123"
},
"query": {
"organizationId": "org_123"
},
"server": {
"subdomain": "acme"
}
}
}
Values inside content are available directly under user. Relevate also supplies:
user.authenticateduser.iduser.emailuser.groupsuser.provider
Sensitive-looking custom claims such as token, secret, and password are removed before content is rendered.
Supported Expressions
Personalization supports values, strict comparisons, ternaries, fragments, nested ternaries, &&, and ||.
{user.role === 'admin' && <Check>Administrator guidance is visible.</Check>}
{user.organization.region === 'eu-west'
? <Info>Examples use the EU endpoint.</Info>
: <Info>Examples use the global endpoint.</Info>}
Use a fragment when a branch needs several elements:
{user.plan === 'enterprise'
? <>
<Tip>Enterprise controls are enabled.</Tip>
<Card title="Usage" href="/guides/usage" icon="chart-bar">
Review workspace usage and limits.
</Card>
</>
: <Warning>This section requires an enterprise plan.</Warning>}
When a branch needs block Markdown—such as headings, lists, tables, or fenced code blocks—wrap that branch in the <MDX> component.
Personalization is intentionally not arbitrary JavaScript. Function calls, assignments, browser globals, and executable expressions are rejected. Dynamic HTML attributes are not supported; put the condition around the element instead.
Reusable MDX And React Components
Personalized branches can contain reusable MDX snippets and React components. Relevate compiles every branch during the build, then renders only the selected branch for the reader.
import EnterprisePanel from '/snippets/enterprise-panel.mdx'
import { UsageChart } from '/snippets/usage-chart.tsx'
{user.plan === 'enterprise'
? <>
<EnterprisePanel />
{user.showUsage && <UsageChart range="30d" />}
</>
: <Warning>Upgrade to view enterprise usage.</Warning>}
The imported MDX snippet can contain its own conditions:
## Enterprise controls
Welcome, {user.firstName}.
{user.role === 'admin'
? <Tip>Admin controls are enabled.</Tip>
: <Note>You have read-only access.</Note>}
React component props must remain build-time JSON-compatible values. Put reader-specific values in the surrounding MDX expression or an imported MDX snippet.
Preview With Test Data
You can test every personalized branch locally without signing in. Create a JSON fixture:
{
"groups": ["admin", "enterprise"],
"content": {
"firstName": "Preview Jane",
"plan": "enterprise",
"role": "admin",
"showUsage": true,
"organization": {
"name": "Acme Observatory",
"region": "eu-west"
}
}
}
Start the preview with that user:
relevate preview --user-data ./personalization.test.json
--user-data implies an authenticated preview user. You can also combine it with --groups when testing group-based access.
Keep several small fixtures—such as anonymous, standard, enterprise, and administrator—so each branch is easy to review before publishing.
Personalized API Playground Defaults
Use apiPlaygroundInputs to prefill examples for the current reader:
{
"apiPlaygroundInputs": {
"header": {
"Authorization": "Bearer local-test-token"
},
"path": {
"organizationId": "org_preview"
},
"query": {
"limit": "10"
}
}
}
Relevate applies only values that match the endpoint's parameters, server variables, or security scheme. A reader's manual playground edit is stored locally and takes precedence on later visits. Generated request examples use the same populated values.
Privacy And Build Behavior
User values are HTML-escaped before entering the response.
Resolved values are never written into search indexes, Markdown exports, or build artifacts.
Both branches are compiled ahead of time; requests do not compile MDX.
Personalized render programs are validated when the documentation instance starts and retained in memory.
Authored source remains the source of truth for assistant and Markdown exports.