Variables
Any token of the form $NAME$ in the source is replaced at
build time with the value declared in options.variables.
Substitution runs as the final pass over the fully rendered page, so the
same syntax reaches content, embedded files, and shell fragments like the
logo and footer.
Syntax
A variable reference is a name in SCREAMING_SNAKE_CASE
bracketed by dollar signs:
0.1.18
Carrot Search
$API_BASE_URL$The name rules:
-
Must start with an uppercase letter.
-
May contain uppercase letters, digits, and underscores.
-
No lowercase — intentional, to keep the placeholders visually distinct from surrounding prose.
An unknown reference is left untouched, so an unreplaced
$FOO$ will appear verbatim in the output. That makes
stale references obvious in review rather than silently disappearing.
Configuration
Declare the map in eleventy.config.js:
import apidocs from "@carrotsearch/eleventy-apidocs";
export default async function (eleventyConfig) {
return apidocs(eleventyConfig, {
contentDir: "src/content",
variables: {
VERSION: "0.1.0",
SITE_OWNER: "Carrot Search",
API_BASE_URL: "https://api.example.com"
}
});
}
Values are coerced with String() on insertion, so numbers,
booleans, and dates all work without ceremony. The build that produced
this page used VERSION = "0.1.18" and
SITE_OWNER = "Carrot Search" — the footer further
down picks up the latter.
Where substitution applies
The variable pass is the last step in the document pipeline. By that
point Nunjucks has already rendered the layout shell around the
content, so any $NAME$ token anywhere in the resulting
HTML is fair game — including in attribute values:
<p>Running version <code>0.1.18</code>.</p>
<a href="$API_BASE_URL$/healthz">Status</a>The same applies to:
- Article content
-
Every page under
contentDir. - Logo and footer fragments
-
Both are rendered as raw HTML before substitution, so a footer like
© Carrot Searchresolves correctly. - Embedded files
-
When a
<pre data-embed>pulls in a file, substitution applies to that file’s contents too. The next section has an example.
Variables in embedded files
Substitution runs over embed contents as they’re loaded, before they’re inserted into the page. That lets a single config snippet pull values from the build:
export async function withVariables(eleventyConfig) {
return apidocs(eleventyConfig, {
contentDir: "src/content",
variables: {
VERSION: "0.1.18",
OWNER: "Carrot Search"
}
});
}
When this page builds, the 0.1.18 and
Carrot Search references inside the embed are resolved
using the same map as the rest of the page — so the snippet
readers see is the snippet the page itself was built with.
This isn’t a template language
Variable substitution is intentionally tiny: token replacement, no conditionals, no loops, no function calls. If you need branching or iteration in content, write a custom pipeline pass — the cheerio API gives you the full document to manipulate, which is a better tool for that job than a string-replace engine.