Table of Contents

Internals

You can run Baseline without knowing any of this. The page exists for the moments when you peek into _snapshot, watch a console log, or follow a stack trace into the plugin and want to know what each piece is called.

Reference register. Brief by design.


Registry

A registry is a per-config bag of state. Baseline keeps one root registry as a WeakMap keyed by eleventyConfig, then carves out named scopes inside it (e.g. core:page-context, core:virtual-dir). Each scope holds three things:

  • a cache (identity-keyed memoisation, used by the page-context builder),
  • a values map (named entries, used by stores),
  • a listeners set (event-listener dedup keys, so re-registering a plugin doesn't double-attach handlers).

Why a WeakMap: Eleventy can run multiple configs in the same Node process (parallel builds, tests, hot reload). Keying by the config instance keeps state isolated and lets it get collected when the config goes out of scope.

The registry source: _baseline/core/registry.js.


Stores

A store is a small wrapper over a registry scope that captures Eleventy's lifecycle events into a value the rest of Baseline can read. Four ship today:

Store Populated by Read by
content-map Eleventy's eleventy.contentMap event The page-context registry, for canonical URL resolution, and the navigator as _snapshot.contentMap.
translation-map The multilang module's collection The wikilinks plugin, while markdown renders, to resolve [[slug:lang]].
translation-index The content graph, same relationships regrouped The head module at transform-time, to emit hreflang alternates.
slug-index The page-context registry, walking default-language pages The wikilinks markdown-it plugin, to resolve [[slug]] targets.

There are two translation stores because the collection-built map exists during the pre-pass and the graph-built index does not.

All four attach exactly one listener per (event, key) pair, courtesy of the registry's listener dedup. Re-registering the plugin is safe.


Virtual directories

A virtual directory is an extra key on eleventyConfig.directories that Eleventy itself does not honour. Baseline adds two: assets and public.

The mechanism: Object.defineProperty adds the key with a getter that reads from a live cache. The cache is pre-populated from eleventyConfig.dir at plugin-init time (so synchronous readers like watch globs see a valid path) and refreshed on eleventy.directories (so the final, normalised paths land before any consumer reads them post-cascade).

Why not just use eleventyConfig.dir.assets? Eleventy's ProjectDirectories.setViaConfigObject() only accepts input, output, data, includes, and layouts. Anything else is silently dropped. Synthesising the keys onto eleventyConfig.directories is the workaround.

The asymmetry between the virtual public key and the on-disk static/ folder is documented in Config export.


Reserved data keys

Baseline pre-registers fifteen reserved keys as empty objects so module-namespaced data merges cleanly and does not collide with same-named filters. The full list (INTERNAL_KEYS):

_baseline, _assets, _head, _multilang, _navigator, _sitemap, _snapshot, _segments, eleventyComputed._pagebreak, eleventyComputed._pageContext, eleventyComputed._node, eleventyComputed._seoGraph, eleventyComputed._backlinks, eleventyComputed._outgoing, eleventyComputed._edges.

Of those, eight are populated on every page: _baseline (env, options, features, paths), _navigator (the cross-page read surface, { nodes, edges, backlinks }), _snapshot (the navigator's per-page debug bundle), eleventyComputed._pageContext, eleventyComputed._seoGraph (the resolved per-page SEO handle the head emits from), eleventyComputed._node (the page's own content-graph node), eleventyComputed._backlinks (edges where to === page.url, as bare edge records), and eleventyComputed._outgoing (edges where from === page.url, same shape). eleventyComputed._edges is reserved and skipped from the cascade-skip block but no value is currently bound.

Two more are populated only where a page splits itself on a content marker: _segments, written by the segmentation preprocessor and carrying the parts the page became, and eleventyComputed._pagebreak, where a template reads the navigation between those parts. A page with no marker leaves both empty.

The per-module _assets, _head, _multilang, _sitemap reservations are namespace placeholders today. See Globals for the populated half.

The _internal: true opt-out is documented on Page context; it skips a template from the page-context registry.


See also