Table of Contents
Debugging with Navigator
When something looks off in a build, Baseline's debug helpers let you see the data Eleventy is working with from inside any template. By the end of this chapter you'll know which helper to reach for, when, and how to keep them out of production. The cost of leaving them in dev is essentially nothing; the cost of shipping them is real.
The navigator is Baseline's built-in inspection surface. It comes in three flavours:
- The debug filters (
_inspect,_json,_keys). Always available. - The runtime helpers (
_runtime(),_ctx()). Always available, and they return live snapshots. - The navigator template. A virtual page Baseline can register at
/navigator-core.html. On in dev by default, off in production.
A snapshot, in this context, is a structured dump of state at the moment it's read.
What you will build
- A debug page that prints selected data through Baseline's filters.
- An inline section using
_runtime(),_ctx(), and_snapshot. - Optionally, the navigator template enabled for a one-page view of the cascade.
Prerequisites
- Baseline installed and loaded, as in previous tutorials.
- A sample page already exists (e.g. from the simple site tutorial).
package.jsonwith"type": "module"and thedev/buildscripts:{ "name": "simple-baseline-site", "type": "module", "scripts": { "start": "rimraf dist/ && npx @11ty/eleventy --serve", "build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy" } }
1) Enable (or skip) the navigator template
The navigator template is on by default in development and off in production. If that suits you, skip to step 2; no configuration needed.
To control it explicitly, the navigator option takes either a boolean or an object:
import baseline, { config as baselineConfig } from '@apleasantview/eleventy-plugin-baseline';
import settings from './src/_data/settings.js';
/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
export default async function (eleventyConfig) {
eleventyConfig.addPlugin(
baseline(settings, {
navigator: {
template: true,
inspectorDepth: 2
}
})
);
}
export const config = baselineConfig;
inspectorDepth is the default depth _inspect uses, set to 2. Per-call overrides take precedence: {{ page | _inspect({ depth: 4 }) }} uses depth 4 regardless of the global default.
2) Add a debug page
Create src/content/pages/debug-playground.md:
---
title: 'Debug Playground'
description: 'Inspect data with Baseline debug helpers.'
slug: 'debug-playground'
layout: 'layouts/base.njk'
---
## Collections (first 3)
<pre>
{% for item in collections.all.slice(0, 3) %}
- {{ item.url }}
{% endfor %}
</pre>
## Page keys
<pre>{{ _pageContext | _keys }}</pre>
## Page data (inspect)
<pre>{{ _pageContext | _inspect({ getters: true, depth: 2 }) }}</pre>
## Page data (json)
<pre>{{ _pageContext | _json(2) }}</pre>
3) Use the runtime and context helpers inline
Both helpers return live state at render time:
_runtime()returns{ env, ctx, globals }: environment data, the current render context, and registered globals._ctx()returns just the current render context (the samectxyou'd find inside_runtime()).
<h2>Runtime (env + ctx + globals)</h2>
<pre>{{ _runtime() | _inspect() }}</pre>
<h2>Render context only</h2>
<pre>{{ _ctx() | _inspect({ depth: 2 }) }}</pre>
These dumps can be large. Use them locally; remove or guard them before shipping.
4) Read the _snapshot global
_snapshot is a computed global with the shape { contentMap, pageContext }. The content map is the per-build inventory of pages; pageContext is the full normalised map of all your content and modules read from internally.
<h2>Content map</h2>
<pre>{{ _snapshot.contentMap | _json(2) }}</pre>
<h2>Page context</h2>
<pre>{{ _snapshot.pageContext | _json(2) }}</pre>
One quirk worth knowing: _snapshot.contentMap is null on the navigator template itself, because the content-map event hasn't fired yet at that point in the lifecycle. Read it from any ordinary page instead.
5) Run and inspect
npm start
Open /debug-playground/ to see the filters and global outputs.
6) Visit the navigator template (optional)
With navigator.template: true, Baseline registers a virtual page at /navigator-core.html. It renders the same kind of snapshot as _runtime(), but as its own page rather than embedded in one of yours. Keep it disabled in production.
7) Production considerations
- Set
navigator: falsefor production builds. _runtime()and_ctx()expose the full render context, including data-layer values you don't want public. Remove them from any template you ship._inspectand_jsonare safe to leave registered, but watch what you pipe into them on a production page.
Next steps
- Mark debug pages with
draft: trueso they stay out of production automatically. The sitemaps and drafts tutorial covers the rest of the draft story. - Narrow your inspection by slicing collections or selecting specific data keys before piping them into a filter. Bigger dumps aren't always more useful.
- The navigator module reference has the full option shape; the globals reference covers
_snapshotand_baseline.features; the filters reference lists the debug filters.
Previous: Deployment URL Checks
Next: How-To's