navigator
INTERNAL_KEY: '_navigator'
What it does
The navigator module wears two hats. It is Baseline's runtime-introspection surface, and it is the public read surface for plugin-produced cross-page data.
As the runtime-introspection surface, the navigator gives every install a single page that dumps the current state of the build: Eleventy's render context (the values Nunjucks has in scope), Baseline's runtime stores, the resolved options, the page-context registry. The mental model is closer to PHP's phpinfo() than to a stack-trace overlay; you visit /navigator-core.html to answer "what is actually configured right now?" without pausing the build or wiring a debugger.
The supporting tools are two Nunjucks globals (_runtime, _ctx), three filters (_inspect, _json, _keys), a computed _snapshot of Baseline's runtime state, and the virtual page itself (a synthetic template Baseline injects into the build, not a file you write) at /navigator-core.html. The same tools work in any template you author, so you can drop targeted inspection into a layout without enabling the virtual page.
As the public read surface, it registers the _navigator Nunjucks global with shape { nodes, edges, backlinks }. nodes is the per-URL map from the content graph; edges is a flat array of every link in the graph; backlinks is the target-keyed enriched backlinks map.
Authors paginate over _navigator.backlinks to generate "what links here" subpages, or read _navigator.nodes and _navigator.edges for cross-page features (related-page lists, navigation indices, link audits). The per-page view of the same substrate is on data._node, data._backlinks, and data._outgoing; see Globals.
_runtimeand_ctxdump the full render context and may include secrets from your data layer or environment. Only use them in local development or secured environments.
Active when
Always. The module loads unconditionally, so _navigator, _runtime, _ctx, the debug filters, and the computed _snapshot are available on every build. The navigator option governs the virtual page only:
navigator: true(the default whenELEVENTY_ENV=development): virtual page enabled.navigator: false(the default otherwise): virtual page suppressed. Globals and filters still register.navigator: { template, inspectorDepth }: virtual page enabled whentemplateis truthy, inspector depth tuned byinspectorDepth.
Lifecycle
- Build-time. Registers the Nunjucks globals, the debug filters, the computed
_snapshot, and (when enabled) the virtual page at/navigator-core.html. - Cascade-time.
_snapshotresolves on every page; itscontentMapandpageContextfields are read from the runtime stores.
How it works
- Resolve options. The module reads
options.navigatorfrom state. Boolean shorthand activates the virtual page; object form unwraps to{ template, inspectorDepth }. - Register
_snapshot. Added aseleventyComputed._snapshot. Resolves per page from the runtime stores. - Register
_navigator. Added as a global thunk reading{ nodes, edges, backlinks }fromruntime.contentGraph. Empty objects (or array) when the graph is unavailable, so templates can read it without guarding. - Register debug globals.
_runtimeand_ctxare added as Nunjucks globals. - Register debug filters.
_inspect,_json,_keys. - Register the virtual page (when enabled). A bundled HTML template is read from disk and registered with
permalink: '/navigator-core.html', excluded from collections.
Defaults
- Virtual page. On in development (
ELEVENTY_ENV=development), off otherwise. - Inspector depth.
4. Controls how deep_inspectrenders nested objects on the virtual page. - Globals. Always registered when the module is loaded.
Options
| Option | Type | Default | Meaning |
|---|---|---|---|
navigator |
boolean | { template?: boolean, inspectorDepth?: number } |
true in dev |
true activates the virtual page; false skips it. Object form lets you set template and inspectorDepth independently: { template: true, inspectorDepth: 6 }. |
Globals
Three Nunjucks globals, available in any template once the module is loaded.
_navigatorreturns{ nodes, edges, backlinks }, the cross-page read surface for plugin-produced data:nodes: the per-URL map from the content graph. Each entry merges identity fields (title,slug,description,lang,locale,date,url,breadcrumbs) with extracted fields (excerpt,headings,sections,images).edges: a flat array of every link in the graph, shape{ internal, from, to, text, rel }. One edge per anchor in each page's extracted root.backlinks: the target-keyed enriched backlinks map,{ targetUrl: Array<{ url, title?, excerpt? }> }. Pre-joined with source title and excerpt.- Use it to paginate over backlinks for "what links here" subpages, or to walk
nodesandedgesfor related-page lists and link audits.
_runtime()returns{ env, ctx, globals }:env: the Nunjucks environment instance (filters, globals, configured engines).ctx: the current render context (the values in scope at this point in the template, includingpage,eleventy, your data cascade).globals: registered Nunjucks globals.
_ctx()returns the render context directly (the samectxobject as_runtime().ctx). A shortcut for the common case.
_runtime and _ctx are functions, called with (). _navigator is a plain object.
Computed _snapshot
Every page receives a computed _snapshot with two fields, read from Baseline's runtime stores:
contentMap: the inputPath ↔ url lookup Baseline builds during the cascade. Used by the head module for canonical resolution.pageContext: the page-context registry's snapshot, keyed by URL. The same per-page context the head module reads at transform-time. See Page context.
_snapshot.contentMap is null on the navigator template itself, because the template renders before Eleventy's eleventy.contentMap event fires. Read _snapshot from any ordinary page to see a populated contentMap.
Debug filters
Three filters registered alongside the globals. Full reference on Filters.
_inspect(value, opts): pretty-prints any value with configurable depth._json(value): stringifies as JSON._keys(value): returns the top-level keys of an object.
The virtual page
When the virtual page is enabled, Baseline registers a synthetic template that lives at /navigator-core.html. The template iterates over _runtime() and renders each key with _inspect at the configured depth.
See the navigator template in action.
Note on the URL: the path still ends in -core.html. That is the historical filename of the bundled template. The user-facing module name is navigator; the URL path may be aligned in a future release.
You do not need the virtual page to use the module. The globals and the computed _snapshot work on any template you author.
Tips
- Tune the depth for the virtual page with the object form:
baseline(settings, { navigator: { template: true, inspectorDepth: 4 } }). The boolean shorthand keeps the default depth of 4. - Pair
_ctx()with_inspecton any page for targeted debugging. You do not need the virtual page for that. - The virtual page renders a large snapshot. Keep it off in production. The default already does, but check your environment if it shows up unexpectedly.
_snapshot.contentMapbeingnullis not a bug; it is the lifecycle (the navigator template renders before the content map is ready). Read_snapshotfrom any ordinary page to see it populated.
Example: inspect on any page
You can drop this in any layout or page to render a quick snapshot:
{% for key, value in _runtime() %}
<details>
<summary><strong>{{ key }}</strong></summary>
{% if value | isString %}
<pre>{{ value | safe }}</pre>
{% else %}
<pre>{{ value | _inspect({ depth: 2 }) }}</pre>
{% endif %}
</details>
{% endfor %}
Peer deps
None.
See also
- Globals for
_runtime,_ctx, and_snapshotfield shapes. - Filters for
_inspect,_json,_keys. - Page context for what
_snapshot.pageContextcontains. - Internals for the runtime stores
_snapshotreads. - The other modules, all introspectable through
_snapshotand_runtime: assets, head, multilang, sitemap. - Tutorial: debugging the navigator