Template Variables
Define and use template variables to create dynamic, personalized documentation content.
Overview
Template variables let you personalize documentation content for each reader. Define variables in your docs.json, reference them in MDX pages with {{variable_name}} syntax, and readers can switch values using the variable selector in the rendered site.
Variables are resolved at render time using a layered priority system, so authenticated users, URL parameters, and local selections all work seamlessly together.
Variable Types
HolyDocs supports four variable types:
| Type | Description | Example Use |
|---|---|---|
string | Free-text input with a default value | API base URL, project name |
select | Dropdown with predefined options | Language, SDK, region |
secret | Masked input (never persisted server-side) | API keys, tokens |
computed | Derived from other variables via expression | Full endpoint URL |
Defining Variables
Add a variables array to your docs.json:
json{ "variables": [ { "name": "sdk", "type": "select", "label": "SDK", "description": "Your preferred SDK language", "defaultValue": "javascript", "options": ["javascript", "python", "go", "ruby"] }, { "name": "api_base", "type": "string", "label": "API Base URL", "defaultValue": "https://api.example.com" }, { "name": "api_key", "type": "secret", "label": "API Key", "description": "Your personal API key (stored locally, never sent to our servers)" }, { "name": "endpoint", "type": "computed", "label": "Users Endpoint", "expression": "{{api_base}}/v1/users" } ]}
Variable Properties
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique identifier used in {{name}} syntax |
type | string | select | secret | computed | Yes | Variable type |
label | string | No | Display label in the variable switcher UI |
description | string | No | Help text shown below the input |
defaultValue | string | No | Initial value before user interaction |
options | string[] | Only for select | Available choices for the dropdown |
expression | string | Only for computed | Expression that can reference other variables |
Using Variables in MDX
Reference any defined variable with double-brace syntax:
mdx## AuthenticationAll API requests require a Bearer token. Pass your API key in the`Authorization` header:{{curly_open}}{{curly_open}}curly syntax note: use double braces{{curly_close}}{{curly_close}}```bashcurl -H "Authorization: Bearer {{api_key}}" \ {{api_base}}/v1/users```The {{sdk}} SDK provides a helper for this:
When rendered, {{api_key}} and {{api_base}} are replaced with the reader's selected values in real time.
Variables work inside code blocks, inline code, headings, and regular text. They are resolved before the MDX pipeline processes the page, so they work anywhere in your content.
Variable Switcher UI
When variables are defined, a floating variable panel appears on the rendered doc site. Readers can:
- Select values from dropdowns (for
selectvariables) - Type custom values (for
stringvariables) - Enter secrets that are stored only in their browser (for
secretvariables) - See computed values update automatically
Selections persist in the reader's browser via localStorage, so they carry across page navigations and return visits.
Computed Variables
Computed variables derive their value from other variables using expressions. This avoids duplication and keeps content consistent:
json{ "name": "install_command", "type": "computed", "expression": "npm install @{{org_name}}/{{package_name}}"}
Computed expressions can reference any other variable (including other computed variables). HolyDocs resolves them in dependency order.
Circular references between computed variables will result in a build error. For example, if variable a references b and b references a, the build will fail with a clear error message.
Resolution Priority
Variables are resolved using a layered system. Higher layers override lower ones:
Authenticated user context (highest)
If the reader is authenticated, user properties like name, email, and groups are available as variables automatically. These take the highest priority.
URL query parameters
Pass variable values via URL: ?sdk=python&api_base=https://staging.example.com. Useful for sharing pre-configured links.
User local selections
Values the reader has set in the variable switcher, stored in localStorage.
Project defaults (lowest)
The defaultValue from your docs.json variable definitions.
Environment Overrides
Override variable defaults per environment. This is useful when staging and production use different API endpoints:
json{ "variables": [ { "name": "api_base", "type": "string", "defaultValue": "https://api.example.com" } ], "environments": [ { "name": "staging", "branchPattern": "staging/*", "variableOverrides": { "api_base": "https://staging-api.example.com" } } ]}
Authenticated User Variables
When authentication is enabled on your doc site, user properties are available as variables without defining them in docs.json:
| Variable | Description |
|---|---|
{{user.name}} | Authenticated user's display name |
{{user.email}} | Authenticated user's email address |
{{user.groups}} | Comma-separated list of the user's access groups |
mdxWelcome back, {{user.name}}! Your account email is {{user.email}}.
Conditional Content with Variables
Combine variables with the built-in Tabs component to show different content based on context:
mdx<Tabs> <Tab title="JavaScript"> ```javascript import { Client } from '@example/sdk'; const client = new Client('{{api_key}}'); const users = await client.users.list(); ``` </Tab> <Tab title="Python"> ```python from example_sdk import Client client = Client("{{api_key}}") users = client.users.list() ``` </Tab></Tabs>
Sharing Pre-Configured Links
Append variable values as query parameters to share documentation with specific values pre-filled:
texthttps://docs.yourcompany.com/quickstart?sdk=python&api_base=https://eu.api.example.com
This is especially useful for onboarding flows where you want to link users directly to docs with their specific configuration.
Best Practices
Prefer api_base_url over url and organization_name over name. Clear names make your MDX content self-documenting.
Without defaults, unresolved variables render as empty strings. Set sensible defaults so the docs read well even before a reader interacts with the variable switcher.
Secret variables are stored exclusively in the reader's browser. They are never sent to HolyDocs servers or included in build output.
If the same derived value appears in multiple places (like a full API endpoint), define it as a computed variable rather than repeating the expression.