---
title: 'Internals'
description: 'Names for the internals you may run into via the navigator or while debugging: registry, stores, virtual directories, driver seam, reserved keys.'
slug: 'internals'
type: 'article'
date: 2026-04-28T00:00:00.000Z
lang: 'en'
url: 'https://www.eleventy-baseline.dev/docs/core-reference/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`](_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. Three ship today:

- **content-map store** - captures `eleventy.contentMap` and exposes it to the page-context registry (canonical URL resolution) and the navigator (`_snapshot.contentMap`).
- **translation-map store** - populated by the multilang module; read by the head module at transform-time to emit hreflang alternates.
- **slug-index store** - populated by the page-context registry as it walks default-language pages; read by the wikilinks markdown-it plugin to resolve `[[slug]]` targets.

All three 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 | Config export]].

---

## Reserved data keys

Baseline pre-registers twelve 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`, `eleventyComputed._pageContext`, `eleventyComputed._node`, `eleventyComputed._edges`, `eleventyComputed._backlinks`, `eleventyComputed._outgoing`.

Of those, seven are populated today: `_baseline` (env, features, paths), `_navigator` (the cross-page read surface, `{ nodes, edges, backlinks }`), `_snapshot` (the navigator's per-page debug bundle), `eleventyComputed._pageContext`, `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.

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

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

---

## See also

- [[globals | Globals]] - the populated half of `INTERNAL_KEYS`.
- [[config-export | Config export]] - virtual `public` vs on-disk `static/`.
- [[page-context | Page context]] - the registry's most-read consumer.
