Eleventy Baseline Navigator

Start building your site, skip the recurring setup work.

 Go back

Navigator

Page Context
{ site:
   { title: 'Eleventy Baseline',
     tagline: 'Start building your site and skip the recurring setup work.',
     description: '',
     url: 'https://www.eleventy-baseline.dev',
     noindex: false },
  page:
   { inputPath: './src/navigator-core.html',
     fileSlug: 'navigator-core',
     filePathStem: '/navigator-core',
     outputFileExtension: 'html',
     templateSyntax: 'njk',
     date: 2026-06-08T15:47:32.302Z,
     url: '/navigator-core.html',
     outputPath: './dist/navigator-core.html',
     lang: 'en',
     locale: 'en',
     translationKey: undefined,
     isDefaultLang: true,
     sitemap: { ignore: false, changefreq: '', priority: -1 } },
  entry:
   { title: 'Navigator Core',
     description: 'Eleventy + Baseline internals',
     excerpt: undefined,
     slug: 'navigator-core',
     section: undefined,
     type: undefined,
     head: undefined,
     breadcrumbs: [] },
  query: { isHome: false },
  meta:
   { title: 'Navigator Core | Eleventy Baseline',
     description: 'Eleventy + Baseline internals',
     canonical: 'https://www.eleventy-baseline.dev/navigator-core.html',
     robots: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1',
     noindex: false },
  render: { generator: 'Eleventy v3.1.5' },
  head:
   { link:
      [ { rel: 'stylesheet',
          href: 'https://www.eleventy-baseline.dev/assets/css/index.css' },
        { rel: 'me', href: 'https://mastodon.social/@crisverstraeten' },
        { rel: 'icon',
          type: 'image/png',
          href: 'https://www.eleventy-baseline.dev/favicon-96x96.png',
          sizes: '96x96' },
        { rel: 'icon',
          type: 'image/svg+xml',
          href: 'https://www.eleventy-baseline.dev/favicon.svg' },
        { rel: 'shortcut icon', href: 'https://www.eleventy-baseline.dev/favicon.ico' },
        { rel: 'apple-touch-icon',
          href: 'https://www.eleventy-baseline.dev/apple-touch-icon.png' },
        { rel: 'manifest', href: 'https://www.eleventy-baseline.dev/site.webmanifest' } ],
     script:
      [ { src: '/assets/js/index.js', defer: true },
        { src: '/assets/js/vendor/index.js', defer: true } ],
     style: [],
     meta:
      [ { name: 'color-scheme', content: 'light dark' },
        { name: 'theme-color', content: '#ffffff' } ] } }
env
Environment {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  opts:
   { dev: true,
     autoescape: true,
     throwOnUndefined: false,
     trimBlocks: false,
     lstripBlocks: false },
  loaders:
   [ FileSystemLoader {
       _events:
        [Object: null prototype] { update: [Function (anonymous)], load: [Function (anonymous)] },
       _eventsCount: 2,
       _maxListeners: undefined,
       pathsToNames: {},
       noCache: false,
       searchPaths: [ 'src/_includes/', '/opt/build/repo' ],
       cache: {},
       [Symbol(shapeMode)]: false,
       [Symbol(kCapture)]: false } ],
  globals:
   { range: [Function: range],
     cycler: [Function: cycler],
     joiner: [Function: joiner],
     date: { toUTCISO: [Function: toUTCISO] },
     _runtime: [Function: fn],
     _ctx: [Function: fn] },
  filters:
   { abs: [Function: abs],
     batch: [Function: batch],
     capitalize: [Function: capitalize],
     center: [Function: center],
     default: [Function: default_],
     dictsort: [Function: dictsort],
     dump: [Function: dump],
     escape: [Function: escape],
     safe: [Function: safe],
     first: [Function: first],
     forceescape: [Function: forceescape],
     groupby: [Function: groupby],
     indent: [Function: indent],
     join: [Function: join],
     last: [Function: last],
     length: [Function: lengthFilter],
     list: [Function: list],
     lower: [Function: lower],
     nl2br: [Function: nl2br],
     random: [Function: random],
     reject: [Function: filter],
     rejectattr: [Function: rejectattr],
     select: [Function: filter],
     selectattr: [Function: selectattr],
     replace: [Function: replace],
     reverse: [Function: reverse],
     round: [Function: round],
     slice: [Function: slice],
     sum: [Function: sum],
     sort: [Function: macro],
     string: [Function: string],
     striptags: [Function: striptags],
     title: [Function: title],
     trim: [Function: trim],
     truncate: [Function: truncate],
     upper: [Function: upper],
     urlencode: [Function: urlencode],
     urlize: [Function: urlize],
     wordcount: [Function: wordcount],
     float: [Function: float],
     int: [Function: macro],
     d: [Function: default_],
     e: [Function: escape],
     inputPathToUrl: [Function (anonymous)],
     slug: [Function (anonymous)],
     slugify: [Function (anonymous)],
     url: [Function (anonymous)],
     log: [Function (anonymous)],
     getCollectionItemIndex: [Function (anonymous)],
     getCollectionItem: [Function (anonymous)],
     getPreviousCollectionItem: [Function (anonymous)],
     getNextCollectionItem: [Function (anonymous)],
     unique: [Function (anonymous)],
     addPathPrefixToFullUrl: [Function (anonymous)],
     htmlBaseUrl: [Function (anonymous)],
     locale_url: [Function (anonymous)],
     locale_links: [Function (anonymous)],
     locale_page: [Function (anonymous)],
     i18nTranslationsFor: [Function (anonymous)],
     i18nTranslationIn: [Function (anonymous)],
     i18nDefaultTranslation: [Function (anonymous)],
     _inspect: [Function (anonymous)],
     _json: [Function (anonymous)],
     _keys: [Function (anonymous)],
     markdownify: [Function (anonymous)],
     relatedPosts: [Function (anonymous)],
     isString: [Function (anonymous)],
     renderTransforms: [Function (anonymous)],
     transformWithHtmlBase: [Function (anonymous)],
     inlineESbuild: [Function (anonymous)],
     inlinePostCSS: [Function (anonymous)] },
  tests:
   { callable: [Function: callable],
     defined: [Function: defined],
     divisibleby: [Function: divisibleby],
     escaped: [Function: escaped],
     equalto: [Function: equalto],
     eq: [Function: equalto],
     sameas: [Function: equalto],
     even: [Function: even],
     falsy: [Function: falsy],
     ge: [Function: ge],
     greaterthan: [Function: greaterthan],
     gt: [Function: greaterthan],
     le: [Function: le],
     lessthan: [Function: lessthan],
     lt: [Function: lessthan],
     lower: [Function: lower],
     ne: [Function: ne],
     null: [Function: nullTest],
     number: [Function: number],
     odd: [Function: odd],
     string: [Function: string],
     truthy: [Function: truthy],
     undefined: [Function: undefinedTest],
     upper: [Function: upper],
     iterable: [Function: iterable],
     mapping: [Function: mapping] },
  asyncFilters:
   [ 'renderTransforms', 'transformWithHtmlBase', 'inlineESbuild', 'inlinePostCSS' ],
  extensions:
   { setAsync:
      PairedShortcodeFunction {
        tags: [ 'setAsync' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'setAsync' },
     getBundle:
      ShortcodeFunction {
        tags: [ 'getBundle' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'getBundle' },
     getBundleFileUrl:
      ShortcodeFunction {
        tags: [ 'getBundleFileUrl' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'getBundleFileUrl' },
     image:
      ShortcodeFunction {
        tags: [ 'image' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'image' },
     alertBlock:
      PairedShortcodeFunction {
        tags: [ 'alertBlock' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'alertBlock' },
     stepsBlock:
      PairedShortcodeFunction {
        tags: [ 'stepsBlock' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'stepsBlock' },
     tableBlock:
      PairedShortcodeFunction {
        tags: [ 'tableBlock' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'tableBlock' },
     deckBlock:
      PairedShortcodeFunction {
        tags: [ 'deckBlock' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'deckBlock' },
     highlight:
      PairedShortcodeFunction {
        tags: [ 'highlight' ],
        parse: [Function (anonymous)],
        run: [Function (anonymous)],
        __name: 'highlight' } },
  extensionsList:
   [ PairedShortcodeFunction {
       tags: [ 'setAsync' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'setAsync' },
     ShortcodeFunction {
       tags: [ 'getBundle' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'getBundle' },
     ShortcodeFunction {
       tags: [ 'getBundleFileUrl' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'getBundleFileUrl' },
     ShortcodeFunction {
       tags: [ 'image' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'image' },
     PairedShortcodeFunction {
       tags: [ 'alertBlock' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'alertBlock' },
     PairedShortcodeFunction {
       tags: [ 'stepsBlock' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'stepsBlock' },
     PairedShortcodeFunction {
       tags: [ 'tableBlock' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'tableBlock' },
     PairedShortcodeFunction {
       tags: [ 'deckBlock' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'deckBlock' },
     PairedShortcodeFunction {
       tags: [ 'highlight' ],
       parse: [Function (anonymous)],
       run: [Function (anonymous)],
       __name: 'highlight' } ],
  [Symbol(shapeMode)]: false,
  [Symbol(kCapture)]: false }
ctx
{ helpers: { buildCommit: [Function: buildCommit] },
  schema:
   { organization:
      { '@type': 'Organization',
        name: 'a pleasant view',
        legalName: null,
        url: 'https://www.apleasantview.com/',
        email: 'hello@apleasantview.com',
        telephone: null,
        address: null,
        geo: null,
        areaServed: null,
        taxID: '60532955',
        vatID: null,
        foundingDate: null,
        logo: { url: 'https://www.eleventy-baseline.dev/logo.png', width: 400, height: 400 },
        sameAs:
         [ 'https://mastodon.social/@crisverstraeten',
           'https://github.com/apleasantview',
           'https://www.linkedin.com/company/apleasantview' ],
        knowsAbout:
         [ 'Eleventy',
           'Static site generators',
           'Plugin architecture',
           'Web standards',
           'Open source software' ],
        slogan: null },
     person:
      { '@type': 'Person',
        name: 'Cristovao Verstraeten',
        givenName: 'Cristovao',
        familyName: 'Verstraeten',
        url: 'https://www.apleasantview.com/about/',
        email: null,
        image: null,
        jobTitle: 'Independent software developer',
        sameAs:
         [ 'https://mastodon.social/@crisverstraeten',
           'https://github.com/cristovaov',
           'https://www.linkedin.com/in/cristovaoverstraeten/' ] } },
  settings:
   { title: 'Eleventy Baseline',
     tagline: 'Start building your site, skip the recurring setup work.',
     url: 'https://www.eleventy-baseline.dev',
     noindex: false,
     defaultLanguage: 'en',
     languages:
      { en:
         { contentDir: 'content/en/',
           locale: 'en',
           languageName: 'English',
           title: 'Eleventy Baseline',
           tagline: 'Start building your site and skip the recurring setup work.' },
        nl:
         { contentDir: 'content/nl/',
           locale: 'nl',
           languageName: 'Nederlands',
           title: 'Eleventy Baseline',
           tagline: 'Een rit op een magisch tapijt' },
        fr:
         { contentDir: 'content/fr/',
           locale: 'fr',
           languageName: 'Français',
           title: 'Eleventy Baseline',
           tagline: 'Un tour en tapis volant' } },
     head:
      { link:
         [ { rel: 'stylesheet',
             href: 'https://www.eleventy-baseline.dev/assets/css/index.css' },
           { rel: 'me', href: 'https://mastodon.social/@crisverstraeten' },
           { rel: 'icon',
             type: 'image/png',
             href: 'https://www.eleventy-baseline.dev/favicon-96x96.png',
             sizes: '96x96' },
           { rel: 'icon',
             type: 'image/svg+xml',
             href: 'https://www.eleventy-baseline.dev/favicon.svg' },
           { rel: 'shortcut icon', href: 'https://www.eleventy-baseline.dev/favicon.ico' },
           { rel: 'apple-touch-icon',
             href: 'https://www.eleventy-baseline.dev/apple-touch-icon.png' },
           { rel: 'manifest', href: 'https://www.eleventy-baseline.dev/site.webmanifest' } ],
        script:
         [ { src: '/assets/js/index.js', defer: true },
           { src: '/assets/js/vendor/index.js', defer: true } ],
        meta:
         [ { name: 'color-scheme', content: 'light dark' },
           { name: 'theme-color', content: '#ffffff' } ] },
     seo:
      { preserveQueryParams: false,
        ogImage:
         { url: 'https://www.eleventy-baseline.dev/og.jpg',
           width: 1200,
           height: 630,
           alt: 'Eleventy Baseline' },
        openGraph: { type: 'website' },
        twitter: { card: 'summary_large_image' } } },
  _baseline:
   { version: '0.1.0-next.42',
     name: 'Eleventy Baseline',
     env: { mode: 'production', package: '@apleasantview/eleventy-plugin-baseline' },
     options:
      { verbose: true,
        multilang: true,
        sitemap: true,
        navigator: true,
        head: { titleSeparator: ' | ', showGenerator: true },
        assets: { esbuild: {} } },
     features:
      { multilang: true,
        sitemap: true,
        navigator: true,
        head: true,
        assets: true,
        hasImageTransformPlugin: false },
     paths:
      { input: './src/',
        output: './dist/',
        includes: './src/_includes/',
        data: './src/_data/',
        assets: './src/assets/',
        public: './src/static/' } },
  _assets: {},
  _head: {},
  _multilang: {},
  _navigator:
   { nodes:
      { '/about/':
         { title: 'About Eleventy Baseline',
           slug: 'about',
           description:
            'How a personal client-work starter became an opinionated infrastructure plugin for Eleventy.',
           section: undefined,
           breadcrumbs: [],
           type: 'about',
           lang: 'en',
           locale: 'en',
           translationKey: 'about',
           isDefaultLang: true,
           date: 2026-05-23T00:00:00.000Z,
           url: '/about/',
           excerpt:
            "Baseline is an opinionated Eleventy plugin that handles the structural decisions you'd otherwise wire up on every project. Looking for the marketing pitch? It's over on the docs overview.",
           headings: [ [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object] ],
           images: [] },
        '/agent-discovery/':
         { title: 'Agent discovery',
           slug: 'agent-discovery',
           description: 'Static discovery surfaces for AI agents and integrations.',
           section: undefined,
           breadcrumbs: [],
           type: 'page',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-05-22T00:00:00.000Z,
           url: '/agent-discovery/',
           excerpt:
            'This site exposes a handful of static surfaces that AI agents, search crawlers, and integrations can read without parsing HTML. They are generated at build time and cross-reference each other.',
           headings: [ [Object] ],
           sections: [],
           images: [] },
        '/':
         { title: 'Eleventy Baseline',
           slug: 'home',
           description:
            'Eleventy Baseline is a plugin for Eleventy that provides a ready-made site foundation with assets, metadata, and a live content graph that keeps rendered output in sync.',
           section: undefined,
           breadcrumbs: [],
           type: 'page',
           lang: 'en',
           locale: 'en',
           translationKey: 'homepage',
           isDefaultLang: true,
           date: 2026-05-17T00:00:00.000Z,
           url: '/',
           excerpt:
            'Every working Eleventy site rebuilds the same foundation: asset compilation, head tags, sitemap, image handling. The same groundwork every time.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object] ],
           images: [] },
        '/fr/':
         { title: 'Eleventy Baseline',
           slug: 'home',
           description:
            "Eleventy Baseline est un plugin pour Eleventy qui fournit une fondation de site prête à l'emploi, avec les assets, les métadonnées et un graphe de contenu vivant qui maintient la sortie rendue synchronisée.",
           section: undefined,
           breadcrumbs: [],
           type: 'page',
           lang: 'fr',
           locale: 'fr',
           translationKey: 'homepage',
           isDefaultLang: false,
           date: 2026-05-17T00:00:00.000Z,
           url: '/fr/',
           excerpt:
            'Chaque site Eleventy en production reconstruit la même fondation : compilation des assets, balises head, sitemap, gestion des images. Les mêmes fondations à refaire à chaque fois.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object] ],
           images: [] },
        '/nl/':
         { title: 'Eleventy Baseline',
           slug: 'home',
           description:
            'Eleventy Baseline is een plugin voor Eleventy die een kant-en-klare sitebasis biedt met assets, metadata en een levende content graph die de gerenderde output gesynchroniseerd houdt.',
           section: undefined,
           breadcrumbs: [],
           type: 'page',
           lang: 'nl',
           locale: 'nl',
           translationKey: 'homepage',
           isDefaultLang: false,
           date: 2026-05-17T00:00:00.000Z,
           url: '/nl/',
           excerpt:
            'Elke werkende Eleventy-site bouwt dezelfde basis opnieuw op: assets compileren, head-tags, sitemap, beeldverwerking. Steeds hetzelfde grondwerk.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object] ],
           images: [] },
        '/faq/':
         { title: 'FAQ',
           slug: 'faq',
           description:
            'Common questions about Eleventy Baseline: lock-in, scope, production-readiness, tooling, SEO, and support.',
           section: undefined,
           breadcrumbs: [],
           type: 'page',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-06-02T00:00:00.000Z,
           url: '/faq/',
           excerpt:
            "No. It's a standard Eleventy plugin. Take it out and your Eleventy site still builds: you keep your content, your config, your output. Baseline adds conventions and wiring, not a cage.",
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/release-notes/':
         { title: 'Release notes',
           slug: 'release-notes',
           description:
            'Eleventy Baseline ships on a rolling release cadence (`0.1.0-next.X`). Things shift, break, and get renamed between releases. Where a change needs you to do something, the line you have to change is right there with it.',
           section: undefined,
           breadcrumbs: [],
           type: 'page',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-06-04T00:00:00.000Z,
           url: '/release-notes/',
           excerpt:
            'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.',
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/':
         { title: 'Documentation',
           slug: 'docs',
           description:
            'Documentation for the Eleventy Baseline plugin: introduction, tutorials, how-tos, references, and module pages.',
           section: undefined,
           breadcrumbs: [],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/',
           excerpt: 'The documentation for Baseline. Each chapter with its own job:',
           headings: [ [Object], [Object], [Object] ],
           sections: [ [Object], [Object] ],
           images: [] },
        '/docs/introduction/':
         { title: 'Introduction',
           slug: 'introduction',
           description:
            'Start here: what Baseline is, who it is for, the mental model, and a quickstart.',
           section: [ 'docs', 'introduction' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/introduction/',
           excerpt:
            'Start here. The overview is what Baseline is and whether it is for you. The quickstart gets you a running site.',
           headings: [ [Object], [Object] ],
           sections: [ [Object] ],
           images: [] },
        '/docs/introduction/overview/':
         { title: 'Overview',
           slug: 'overview',
           description:
            'What Baseline is, who it is for, why it is a plugin, and what it gives you out of the box.',
           section: [ 'docs', 'introduction' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/introduction/overview/',
           excerpt:
            'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/introduction/quickstart/':
         { title: 'Quickstart',
           slug: 'quickstart',
           description: 'The minimum working setup: install, configure, run.',
           section: [ 'docs', 'introduction' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/introduction/quickstart/',
           excerpt:
            'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.',
           headings:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/concept/':
         { title: 'Concept',
           slug: 'concept',
           description:
            'Explains the foundational concept behind the plugin and how its structure, content organization, and architecture work together.',
           section: [ 'docs', 'concept' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/concept/',
           excerpt:
            'The concept overview is the mental model behind the plugin. Project structure are the small set of rules that keep Baseline out of your way, and content organisation is the page-data pattern those rules assume.',
           headings: [ [Object], [Object] ],
           sections: [ [Object] ],
           images: [] },
        '/docs/concept/concept-overview/':
         { title: 'Concept overview',
           slug: 'concept-overview',
           description:
            'A conceptual map of Baseline: what it handles, the placeholder, and the two configuration surfaces.',
           section: [ 'docs', 'concept' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/concept/concept-overview/',
           excerpt:
            'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.',
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/concept/project-structure/':
         { title: 'Project structure',
           slug: 'project-structure',
           description:
            'How to stay in step with Baseline so the plugin stays out of your way: project shape, the plugin call, settings, options, environment variables, and the small set of seams Baseline expects to own.',
           section: [ 'docs', 'concept' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-05-02T00:00:00.000Z,
           url: '/docs/concept/project-structure/',
           excerpt:
            "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 3 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/concept/content-organisation/':
         { title: 'Content organisation',
           slug: 'content-organisation',
           description:
            'Two layers behind every page: structural metadata (section, type, layout, permalink) lives in a sibling `*.11tydata.js`; content metadata (title, description, date) lives in front matter. A pattern, not a Baseline rule.',
           section: [ 'docs', 'concept' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-05-02T00:00:00.000Z,
           url: '/docs/concept/content-organisation/',
           excerpt: 'Every page on a Baseline site has two layers behind it.',
           headings:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/concept/content-helpers/':
         { title: 'Content helpers',
           slug: 'content-helpers',
           description:
            'How drafts, wikilinks, heading IDs, element attributes, and image handling work in Baseline, and the rules that keep content predictable.',
           section: [ 'docs', 'concept' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-05-02T00:00:00.000Z,
           url: '/docs/concept/content-helpers/',
           excerpt:
            'This section covers the small but important pieces that keep content predictable as it scales.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/concept/architecture-snapshot/':
         { title: 'Architecture snapshot',
           slug: 'architecture-snapshot',
           description:
            'The three-layer model behind baseline: state, runtime, modules. Why it is built that way and how the layers talk to each other.',
           section: [ 'docs', 'concept' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/concept/architecture-snapshot/',
           excerpt: 'The plugin is built in three concentric layers, each with one strict job.',
           headings:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/tutorial/':
         { title: 'Tutorials',
           slug: 'tutorial',
           description:
            'Browse Baseline tutorials: build a simple site, the assets pipeline, the image shortcode, head and noindex, sitemaps and drafts, multilingual, deployment URL checks, and debugging with the navigator.',
           section: [ 'docs', 'tutorial' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/tutorial/',
           excerpt:
            'These are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the feature guides chapter.',
           headings: [ [Object], [Object] ],
           sections: [ [Object] ],
           images: [] },
        '/docs/tutorial/simple-baseline-site/':
         { title: 'Build a simple site',
           slug: 'simple-baseline-site',
           description:
            'Create a single-language Eleventy site with Baseline defaults, head extras driven by settings, minimal CSS/JS, and an auto sitemap.',
           section: [ 'docs', 'tutorial' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/tutorial/simple-baseline-site/',
           excerpt:
            "The shortest path from an empty folder to a working Baseline site. By the end you'll have a single page rendering through Eleventy, a tiny stylesheet bundled automatically, and a sitemap that updates itself.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 4 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 3 more items ],
           images: [] },
        '/docs/tutorial/multilingual-baseline-site/':
         { title: 'Build a multilingual site',
           slug: 'multilingual-baseline-site',
           description:
            'Build an English and Dutch Baseline site with explicit multilingual opt-in, hreflang links emitted by Baseline, per-language sitemaps, and environment-driven URLs.',
           section: [ 'docs', 'tutorial' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-26T00:00:00.000Z,
           url: '/docs/tutorial/multilingual-baseline-site/',
           excerpt:
            "Add a second language to a Baseline site, with everything you'd expect: per-language URLs, hreflang on every page, a sitemap for each language plus an index.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 5 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 4 more items ],
           images: [] },
        '/docs/feature-guide/':
         { title: 'Feature guides',
           slug: 'feature-guide',
           description: '',
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-05-03T00:00:00.000Z,
           url: '/docs/feature-guide/',
           excerpt:
            "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off.",
           headings: [ [Object], [Object] ],
           sections: [ [Object] ],
           images: [] },
        '/docs/feature-guide/assets-pipeline/':
         { title: 'Assets pipeline quickstart',
           slug: 'assets-pipeline',
           description:
            "Wire Baseline's assets module: a CSS entry through PostCSS, a JS entry through esbuild, the inline filters, and the difference between dev and production output.",
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-13T00:00:00.000Z,
           url: '/docs/feature-guide/assets-pipeline/',
           excerpt:
            "Ship CSS and JS through Baseline's assets module. By the end you'll have one CSS entry going through PostCSS, one JS entry going through esbuild, and a handle on the inline filters when you need them.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/feature-guide/image-shortcode-basics/':
         { title: 'Image Shortcode Basics',
           slug: 'image-shortcode-basics',
           description:
            "Render responsive images with Baseline's image shortcode: alt and caption, multiple formats and sizes, and verify output in dist/media.",
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-13T00:00:00.000Z,
           url: '/docs/feature-guide/image-shortcode-basics/',
           excerpt: 'Render a responsive image with one line of template code.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/feature-guide/head-and-noindex/':
         { title: 'Head and NoIndex',
           slug: 'head-and-noindex',
           description: 'Set Baseline head defaults, add per-page head extras and block robots.',
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/feature-guide/head-and-noindex/',
           excerpt:
            "Get a clean, correct <head> on every page with one placeholder and a settings file. By the end you'll have site-wide metadata, per-page head extras flowing through settings.head and front matter, and a proper canonical and robots story.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 2 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 1 more item ],
           images: [] },
        '/docs/feature-guide/sitemaps-and-drafts/':
         { title: 'Sitemaps and Drafts',
           slug: 'sitemaps-and-drafts',
           description:
            'Control sitemap entries and drafts in Baseline: set per-page sitemap fields, apply noindex, and see how drafts behave in dev versus build.',
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/feature-guide/sitemaps-and-drafts/',
           excerpt:
            "Control which pages end up in your sitemap, and let work-in-progress pages live alongside published ones without leaking into production. By the end you'll have per-page sitemap controls, a working noindex story, and a draft workflow that behaves differently in dev and build, the way you'd want.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 1 more item ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/feature-guide/deployment-url-checks/':
         { title: 'Deployment URL Checks',
           slug: 'deployment-url-checks',
           description:
            'Keep canonical, sitemap, and links pointing at the right origin across dev, preview, and production by setting URL and pathPrefix correctly and verifying the output.',
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/feature-guide/deployment-url-checks/',
           excerpt:
            'Keep your URLs correct across dev, preview, and production, so canonicals, sitemap entries, and links never leak localhost to the live site. The mechanics are mostly Eleventy and environment variables; this chapter is the small set of habits that keep them honest.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/feature-guide/debugging-navigator/':
         { title: 'Debugging with Navigator',
           slug: 'debugging-navigator',
           description:
            'Use Baseline debug filters and the navigator to inspect Eleventy data, render context, and the page-context snapshot without shipping debug tools to production.',
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-26T00:00:00.000Z,
           url: '/docs/feature-guide/debugging-navigator/',
           excerpt:
            "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.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 1 more item ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/feature-guide/custom-schema/':
         { title: 'Custom schema with schema.pieces',
           slug: 'custom-schema',
           description:
            'Add your own schema.org nodes to the JSON-LD graph through the schema.pieces seam, scoped by the cascade.',
           section: [ 'docs', 'feature-guide' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-06-02T00:00:00.000Z,
           url: '/docs/feature-guide/custom-schema/',
           excerpt:
            "Baseline assembles a complete JSON-LD graph for every page on its own: a WebSite, your Organization or Person identity, the WebPage, an Article where relevant, breadcrumbs, and the image and translation references, all wired together with stable @ids. That spine is automatic. When a page needs something the spine doesn't model, a Service, an FAQPage, a Product, an Event, it comes in through one seam: schema.pieces.",
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/how-to/':
         { title: "How-To's",
           slug: 'how-to',
           description:
            'Task-first recipes for things Baseline does not do for you, plus three guides on integrating Baseline into existing setups.',
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/how-to/',
           excerpt:
            'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.',
           headings: [ [Object], [Object] ],
           sections: [ [Object] ],
           images: [] },
        '/docs/how-to/customise-assets-pipeline/':
         { title: 'Customise the Assets Pipeline',
           slug: 'customise-assets-pipeline',
           description:
            "Override Baseline's fallback PostCSS config, add esbuild entry points, and set targets and minification for the assets module.",
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/how-to/customise-assets-pipeline/',
           excerpt:
            'When the fallback configs in the assets module are not enough, drop your own in. PostCSS for CSS, esbuild for JS. The module picks them up.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 6 more items ],
           sections: [ [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/how-to/deploy-under-a-subpath/':
         { title: 'Deploy Under a Subpath',
           slug: 'deploy-under-a-subpath',
           description:
            'Serve your Baseline site from a subpath: set pathPrefix, keep settings.url clean, use root-relative links, and verify sitemap and canonical URLs.',
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/how-to/deploy-under-a-subpath/',
           excerpt:
            'Serve a Baseline site from a subpath like /docs/ without breaking links, asset paths, canonical URLs, or the sitemap on the way.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/how-to/image-transform/':
         { title: 'Image Transform',
           slug: 'image-transform',
           description:
            "Use Eleventy Image's HTML transform to rewrite img tags into responsive picture markup with multiple formats, sizes, and caching, alongside Baseline.",
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-15T00:00:00.000Z,
           url: '/docs/how-to/image-transform/',
           excerpt:
            "The image transform is eleventy-img's, not Baseline's. The two run side by side: eleventyImageTransformPlugin rewrites <img> and <picture> into responsive markup with generated assets and caching, and you add it to your config yourself.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/how-to/multilingual-index/':
         { title: 'Multilingual Index',
           slug: 'multilingual-index',
           description:
            "List your site's pages grouped by language using Baseline's multilingual setup, with a small Nunjucks template and the translationsMap collection.",
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-26T00:00:00.000Z,
           url: '/docs/how-to/multilingual-index/',
           excerpt:
            "A small index page that groups every page on the site by language. Useful when you have a multilingual site and want a single landing point that fans out to each language's content.",
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/how-to/integrate-eleventy-base-blog/':
         { title: 'Integrate with Eleventy Base Blog',
           slug: 'integrate-eleventy-base-blog',
           description:
            'Add @apleasantview/eleventy-plugin-baseline to eleventy-base-blog: install, wire config, align data and assets, migrate head extras, and verify the build.',
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/how-to/integrate-eleventy-base-blog/',
           excerpt: 'This article is planned for revision, its content might be stale.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 7 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 6 more items ],
           images: [] },
        '/docs/how-to/build-scripts-and-cleanup/':
         { title: 'Build Scripts and Cleanup',
           slug: 'build-scripts-and-cleanup',
           description:
            'Use npm-run-all, rimraf, and cross-env to keep Baseline builds clean and predictable for dev and production.',
           section: [ 'docs', 'how-to' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/how-to/build-scripts-and-cleanup/',
           excerpt:
            `A small set of npm scripts that take Baseline's dev and build commands from "works on my machine" to predictable across platforms. Three helpers do the work: rimraf for cleanup, npm-run-all for sequencing, and cross-env for portable env vars.`,
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/':
         { title: 'Core reference',
           slug: 'core-reference',
           description:
            'The inventory of what baseline gives you, grouped as state, runtime, and templating.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/core-reference/',
           excerpt:
            'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.',
           headings: [ [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/plugin-entrypoint/':
         { title: 'Plugin entrypoint',
           slug: 'plugin-entrypoint',
           description:
            'The baseline() factory: signature, options, and what it registers when you add it to Eleventy.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-15T00:00:00.000Z,
           url: '/docs/core-reference/plugin-entrypoint/',
           excerpt:
            'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.',
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/site-settings/':
         { title: 'Site settings',
           slug: 'site-settings',
           description:
            'The settings argument to baseline(): site identity, languages, and head extras.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/site-settings/',
           excerpt:
            'settings is the first argument to baseline(). It carries site identity: title, tagline, canonical URL, indexability, languages, and any extra <head> items you want injected on every page.',
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/config-export/':
         { title: 'Config export',
           slug: 'config-export',
           description:
            'The directory contract baseline ships as a named config export: what it sets, why it matters, and how to override safely.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/config-export/',
           excerpt:
            "Baseline ships a directory contract as a named export. Eleventy's modules expect specific input, output, includes, and data folders; Baseline's modules expect two more (assets, public).",
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/page-context/':
         { title: 'Page context',
           slug: 'page-context',
           description:
            'The normalised per-page object baseline builds at cascade-time and exposes as _pageContext.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/page-context/',
           excerpt:
            "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data.",
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/seo-graph/':
         { title: 'SEO graph',
           slug: 'seo-graph',
           description:
            'The resolved per-page SEO object baseline builds at cascade-time and the head module emits at transform-time: canonical, Open Graph, Twitter, and a JSON-LD graph.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-06-07T00:00:00.000Z,
           url: '/docs/core-reference/seo-graph/',
           excerpt:
            'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/content-graph/':
         { title: 'Content graph',
           slug: 'content-graph',
           description:
            'The queryable map of every rendered page, exposed to templates as _node, _backlinks, _outgoing, and the _navigator global.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-05-14T00:00:00.000Z,
           url: '/docs/core-reference/content-graph/',
           excerpt:
            "A pre-rendered map of every page's headings, images, links, and excerpts, plus the links between pages. Built once before Eleventy's main build by a programmatic dry-run of the site; cached at .cache/_baseline/content-graph.json. Templates read it through cascade keys; modules read it through coreContext.runtime.contentGraph.",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 3 more items ],
           sections:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/internals/':
         { title: 'Internals',
           slug: 'internals',
           description:
            'Names for the internals you may run into via the navigator or while debugging: registry, stores, virtual directories, driver seam, reserved keys.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/internals/',
           excerpt:
            '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.',
           headings: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/filters/':
         { title: 'Filters',
           slug: 'filters',
           description:
            'Filters baseline registers, grouped by module: when each is available and what it does.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/filters/',
           excerpt:
            'Eleventy filters Baseline registers. Some are always available; the rest come on with the module that registers them.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 8 more items ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/globals/':
         { title: 'Globals',
           slug: 'globals',
           description:
            'The data baseline injects into the Eleventy data cascade: _baseline, _pageContext, _snapshot, _node, _backlinks, _outgoing, _navigator, reserved keys, and the date global.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/globals/',
           excerpt:
            'Baseline registers a handful of global data keys and a few Nunjucks globals. Most of them are reference targets you can read in templates; the rest are reserved namespaces that keep module-namespaced data from colliding with filters.',
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 3 more items ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/core-reference/image-shortcode/':
         { title: 'Image shortcode',
           slug: 'image-shortcode',
           description:
            'The image shortcode: responsive <picture>, multiple formats, captions, and on-request transforms in dev. Built on @11ty/eleventy-img.',
           section: [ 'docs', 'core-reference' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-28T00:00:00.000Z,
           url: '/docs/core-reference/image-shortcode/',
           excerpt:
            "The shortcode is Baseline's; the underlying engine is @11ty/eleventy-img. The two halves split cleanly:",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           sections: [ [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/module/':
         { title: 'Modules',
           slug: 'module',
           description: "Baseline's five feature modules: assets, head, multilang, navigator, sitemap.",
           section: [ 'docs', 'module' ],
           breadcrumbs: [ [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-01-25T00:00:00.000Z,
           url: '/docs/module/',
           excerpt:
            'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.',
           headings: [ [Object], [Object], [Object] ],
           sections: [ [Object], [Object] ],
           images: [] },
        '/docs/module/assets/':
         { title: 'assets',
           slug: 'assets',
           description:
            "Baseline's single assets module. Wires JS (esbuild) and CSS (PostCSS) entry points into Eleventy, with compile guards, watch targets, and inline filters for critical-path assets.",
           section: [ 'docs', 'module' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-13T00:00:00.000Z,
           url: '/docs/module/assets/',
           excerpt: "INTERNAL_KEY: '_assets'",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 2 more items ],
           sections:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/module/head/':
         { title: 'head',
           slug: 'head',
           description:
            "The head module composes the page's <head> at transform-time: builds seeds during the cascade, replaces a <baseline-head> placeholder with a sorted, deduped element list.",
           section: [ 'docs', 'module' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-15T00:00:00.000Z,
           url: '/docs/module/head/',
           excerpt: "INTERNAL_KEY: '_head'",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 5 more items ],
           sections:
            [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/docs/module/multilang/':
         { title: 'multilang',
           slug: 'multilang',
           description:
            'Language infrastructure: normalises language config, attaches per-page locale data, builds translation collections, and exposes i18n filters. Opt-in.',
           section: [ 'docs', 'module' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-15T00:00:00.000Z,
           url: '/docs/module/multilang/',
           excerpt: "INTERNAL_KEY: '_multilang'",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 5 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/module/navigator/':
         { title: 'navigator',
           slug: 'navigator',
           description:
            "Two roles: the runtime-introspection surface (Baseline's phpinfo()-style page for current build state), and the public read surface for plugin-produced cross-page data (the content graph and backlinks).",
           section: [ 'docs', 'module' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-15T00:00:00.000Z,
           url: '/docs/module/navigator/',
           excerpt: "INTERNAL_KEY: '_navigator'",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 5 more items ],
           sections:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object] ],
           images: [] },
        '/docs/module/sitemap/':
         { title: 'sitemap',
           slug: 'sitemap',
           description:
            'Generate /sitemap.xml, or per-language sitemaps plus an index when multilang is active. Computed page.sitemap data lets pages opt out from front matter.',
           section: [ 'docs', 'module' ],
           breadcrumbs: [ [Object], [Object], [Object], [Object] ],
           type: 'article',
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-04-15T00:00:00.000Z,
           url: '/docs/module/sitemap/',
           excerpt: "INTERNAL_KEY: '_sitemap'",
           headings:
            [ [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              [Object],
              ... 3 more items ],
           sections: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
           images: [] },
        '/navigator-core.html':
         { title: 'Navigator Core',
           slug: 'navigator-core',
           description: 'Eleventy + Baseline internals',
           section: undefined,
           breadcrumbs: [],
           type: undefined,
           lang: 'en',
           locale: 'en',
           translationKey: undefined,
           isDefaultLang: true,
           date: 2026-06-08T15:47:30.605Z,
           url: '/navigator-core.html',
           excerpt: '← Go back',
           headings: [ [Object] ],
           sections: [],
           images: [] } },
     edges:
      [ { internal: true,
          from: '/about/',
          to: '/docs/introduction/overview/',
          text: 'docs overview',
          rel: [] },
        { internal: false,
          from: '/about/',
          to: 'https://www.apleasantview.com',
          text: 'a pleasant view',
          rel: [] },
        { internal: true, from: '/about/', to: '/', text: 'eleventy-baseline.dev', rel: [] },
        { internal: true, from: '/', to: '/docs/', text: 'docs', rel: [] },
        { internal: true,
          from: '/',
          to: '/docs/introduction/quickstart/',
          text: 'quickstart',
          rel: [] },
        { internal: true, from: '/', to: '/docs/', text: 'docs', rel: [] },
        { internal: true,
          from: '/',
          to: '/docs/tutorial/simple-baseline-site/',
          text: 'simple site tutorial',
          rel: [] },
        { internal: false,
          from: '/',
          to: 'https://github.com/apleasantview/eleventy-plugin-baseline/issues',
          text: 'open an issue',
          rel: [] },
        { internal: false,
          from: '/',
          to: 'https://www.apleasantview.com',
          text: 'a pleasant view',
          rel: [] },
        { internal: true, from: '/fr/', to: '/docs/', text: 'documentation', rel: [] },
        ... 326 more items ],
     backlinks:
      { '/docs/introduction/overview/':
         [ { url: '/about/',
             title: 'About Eleventy Baseline',
             excerpt:
              "Baseline is an opinionated Eleventy plugin that handles the structural decisions you'd otherwise wire up on every project. Looking for the marketing pitch? It's over on the docs overview." },
           { url: '/docs/introduction/',
             title: 'Introduction',
             excerpt:
              'Start here. The overview is what Baseline is and whether it is for you. The quickstart gets you a running site.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/tutorial/',
             title: 'Tutorials',
             excerpt:
              'These are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the feature guides chapter.' },
           { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." } ],
        '/':
         [ { url: '/about/',
             title: 'About Eleventy Baseline',
             excerpt:
              "Baseline is an opinionated Eleventy plugin that handles the structural decisions you'd otherwise wire up on every project. Looking for the marketing pitch? It's over on the docs overview." } ],
        '/docs/':
         [ { url: '/',
             title: 'Eleventy Baseline',
             excerpt:
              'Every working Eleventy site rebuilds the same foundation: asset compilation, head tags, sitemap, image handling. The same groundwork every time.' },
           { url: '/fr/',
             title: 'Eleventy Baseline',
             excerpt:
              'Chaque site Eleventy en production reconstruit la même fondation : compilation des assets, balises head, sitemap, gestion des images. Les mêmes fondations à refaire à chaque fois.' },
           { url: '/nl/',
             title: 'Eleventy Baseline',
             excerpt:
              'Elke werkende Eleventy-site bouwt dezelfde basis opnieuw op: assets compileren, head-tags, sitemap, beeldverwerking. Steeds hetzelfde grondwerk.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' } ],
        '/docs/introduction/quickstart/':
         [ { url: '/',
             title: 'Eleventy Baseline',
             excerpt:
              'Every working Eleventy site rebuilds the same foundation: asset compilation, head tags, sitemap, image handling. The same groundwork every time.' },
           { url: '/fr/',
             title: 'Eleventy Baseline',
             excerpt:
              'Chaque site Eleventy en production reconstruit la même fondation : compilation des assets, balises head, sitemap, gestion des images. Les mêmes fondations à refaire à chaque fois.' },
           { url: '/nl/',
             title: 'Eleventy Baseline',
             excerpt:
              'Elke werkende Eleventy-site bouwt dezelfde basis opnieuw op: assets compileren, head-tags, sitemap, beeldverwerking. Steeds hetzelfde grondwerk.' },
           { url: '/docs/introduction/',
             title: 'Introduction',
             excerpt:
              'Start here. The overview is what Baseline is and whether it is for you. The quickstart gets you a running site.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' },
           { url: '/docs/tutorial/',
             title: 'Tutorials',
             excerpt:
              'These are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the feature guides chapter.' } ],
        '/docs/tutorial/simple-baseline-site/':
         [ { url: '/',
             title: 'Eleventy Baseline',
             excerpt:
              'Every working Eleventy site rebuilds the same foundation: asset compilation, head tags, sitemap, image handling. The same groundwork every time.' },
           { url: '/fr/',
             title: 'Eleventy Baseline',
             excerpt:
              'Chaque site Eleventy en production reconstruit la même fondation : compilation des assets, balises head, sitemap, gestion des images. Les mêmes fondations à refaire à chaque fois.' },
           { url: '/nl/',
             title: 'Eleventy Baseline',
             excerpt:
              'Elke werkende Eleventy-site bouwt dezelfde basis opnieuw op: assets compileren, head-tags, sitemap, beeldverwerking. Steeds hetzelfde grondwerk.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/introduction/quickstart/',
             title: 'Quickstart',
             excerpt:
              'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/tutorial/',
             title: 'Tutorials',
             excerpt:
              'These are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the feature guides chapter.' },
           { url: '/docs/tutorial/multilingual-baseline-site/',
             title: 'Build a multilingual site',
             excerpt:
              "Add a second language to a Baseline site, with everything you'd expect: per-language URLs, hreflang on every page, a sitemap for each language plus an index." },
           { url: '/docs/feature-guide/assets-pipeline/',
             title: 'Assets pipeline quickstart',
             excerpt:
              "Ship CSS and JS through Baseline's assets module. By the end you'll have one CSS entry going through PostCSS, one JS entry going through esbuild, and a handle on the inline filters when you need them." },
           { url: '/docs/feature-guide/head-and-noindex/',
             title: 'Head and NoIndex',
             excerpt:
              "Get a clean, correct <head> on every page with one placeholder and a settings file. By the end you'll have site-wide metadata, per-page head extras flowing through settings.head and front matter, and a proper canonical and robots story." },
           ... 2 more items ],
        '/docs/core-reference/seo-graph/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/page-context/',
             title: 'Page context',
             excerpt:
              "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data." },
           { url: '/docs/core-reference/content-graph/',
             title: 'Content graph',
             excerpt:
              "A pre-rendered map of every page's headings, images, links, and excerpts, plus the links between pages. Built once before Eleventy's main build by a programmatic dry-run of the site; cached at .cache/_baseline/content-graph.json. Templates read it through cascade keys; modules read it through coreContext.runtime.contentGraph." },
           { url: '/docs/module/head/', title: 'head', excerpt: "INTERNAL_KEY: '_head'" } ],
        '/docs/feature-guide/custom-schema/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." },
           { url: '/docs/feature-guide/custom-schema/',
             title: 'Custom schema with schema.pieces',
             excerpt:
              "Baseline assembles a complete JSON-LD graph for every page on its own: a WebSite, your Organization or Person identity, the WebPage, an Article where relevant, breadcrumbs, and the image and translation references, all wired together with stable @ids. That spine is automatic. When a page needs something the spine doesn't model, a Service, an FAQPage, a Product, an Event, it comes in through one seam: schema.pieces." },
           { url: '/docs/core-reference/seo-graph/',
             title: 'SEO graph',
             excerpt:
              'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.' } ],
        '/docs/module/head/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/feature-guide/head-and-noindex/',
             title: 'Head and NoIndex',
             excerpt:
              "Get a clean, correct <head> on every page with one placeholder and a settings file. By the end you'll have site-wide metadata, per-page head extras flowing through settings.head and front matter, and a proper canonical and robots story." },
           { url: '/docs/feature-guide/custom-schema/',
             title: 'Custom schema with schema.pieces',
             excerpt:
              "Baseline assembles a complete JSON-LD graph for every page on its own: a WebSite, your Organization or Person identity, the WebPage, an Article where relevant, breadcrumbs, and the image and translation references, all wired together with stable @ids. That spine is automatic. When a page needs something the spine doesn't model, a Service, an FAQPage, a Product, an Event, it comes in through one seam: schema.pieces." },
           { url: '/docs/how-to/integrate-eleventy-base-blog/',
             title: 'Integrate with Eleventy Base Blog',
             excerpt: 'This article is planned for revision, its content might be stale.' },
           { url: '/docs/core-reference/site-settings/',
             title: 'Site settings',
             excerpt:
              'settings is the first argument to baseline(). It carries site identity: title, tagline, canonical URL, indexability, languages, and any extra <head> items you want injected on every page.' },
           { url: '/docs/core-reference/page-context/',
             title: 'Page context',
             excerpt:
              "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data." },
           { url: '/docs/core-reference/seo-graph/',
             title: 'SEO graph',
             excerpt:
              'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.' },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' },
           ... 2 more items ],
        '/docs/core-reference/site-settings/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/feature-guide/head-and-noindex/',
             title: 'Head and NoIndex',
             excerpt:
              "Get a clean, correct <head> on every page with one placeholder and a settings file. By the end you'll have site-wide metadata, per-page head extras flowing through settings.head and front matter, and a proper canonical and robots story." },
           { url: '/docs/feature-guide/custom-schema/',
             title: 'Custom schema with schema.pieces',
             excerpt:
              "Baseline assembles a complete JSON-LD graph for every page on its own: a WebSite, your Organization or Person identity, the WebPage, an Article where relevant, breadcrumbs, and the image and translation references, all wired together with stable @ids. That spine is automatic. When a page needs something the spine doesn't model, a Service, an FAQPage, a Product, an Event, it comes in through one seam: schema.pieces." },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/core-reference/page-context/',
             title: 'Page context',
             excerpt:
              "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data." },
           { url: '/docs/core-reference/seo-graph/',
             title: 'SEO graph',
             excerpt:
              'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.' },
           { url: '/docs/core-reference/image-shortcode/',
             title: 'Image shortcode',
             excerpt:
              "The shortcode is Baseline's; the underlying engine is @11ty/eleventy-img. The two halves split cleanly:" },
           ... 3 more items ],
        '/docs/core-reference/content-graph/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/page-context/',
             title: 'Page context',
             excerpt:
              "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data." } ],
        '/docs/module/navigator/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/feature-guide/debugging-navigator/',
             title: 'Debugging with Navigator',
             excerpt:
              "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." },
           { url: '/docs/how-to/integrate-eleventy-base-blog/',
             title: 'Integrate with Eleventy Base Blog',
             excerpt: 'This article is planned for revision, its content might be stale.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/core-reference/content-graph/',
             title: 'Content graph',
             excerpt:
              "A pre-rendered map of every page's headings, images, links, and excerpts, plus the links between pages. Built once before Eleventy's main build by a programmatic dry-run of the site; cached at .cache/_baseline/content-graph.json. Templates read it through cascade keys; modules read it through coreContext.runtime.contentGraph." },
           { url: '/docs/core-reference/filters/',
             title: 'Filters',
             excerpt:
              'Eleventy filters Baseline registers. Some are always available; the rest come on with the module that registers them.' },
           { url: '/docs/core-reference/globals/',
             title: 'Globals',
             excerpt:
              'Baseline registers a handful of global data keys and a few Nunjucks globals. Most of them are reference targets you can read in templates; the rest are reserved namespaces that keep module-namespaced data from colliding with filters.' },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' } ],
        '/docs/core-reference/globals/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' },
           { url: '/docs/feature-guide/debugging-navigator/',
             title: 'Debugging with Navigator',
             excerpt:
              "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." },
           { url: '/docs/how-to/customise-assets-pipeline/',
             title: 'Customise the Assets Pipeline',
             excerpt:
              'When the fallback configs in the assets module are not enough, drop your own in. PostCSS for CSS, esbuild for JS. The module picks them up.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/core-reference/page-context/',
             title: 'Page context',
             excerpt:
              "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data." },
           { url: '/docs/core-reference/seo-graph/',
             title: 'SEO graph',
             excerpt:
              'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.' },
           { url: '/docs/core-reference/content-graph/',
             title: 'Content graph',
             excerpt:
              "A pre-rendered map of every page's headings, images, links, and excerpts, plus the links between pages. Built once before Eleventy's main build by a programmatic dry-run of the site; cached at .cache/_baseline/content-graph.json. Templates read it through cascade keys; modules read it through coreContext.runtime.contentGraph." },
           ... 2 more items ],
        '/docs/module/multilang/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/tutorial/multilingual-baseline-site/',
             title: 'Build a multilingual site',
             excerpt:
              "Add a second language to a Baseline site, with everything you'd expect: per-language URLs, hreflang on every page, a sitemap for each language plus an index." },
           { url: '/docs/how-to/multilingual-index/',
             title: 'Multilingual Index',
             excerpt:
              "A small index page that groups every page on the site by language. Useful when you have a multilingual site and want a single landing point that fans out to each language's content." },
           { url: '/docs/core-reference/site-settings/',
             title: 'Site settings',
             excerpt:
              'settings is the first argument to baseline(). It carries site identity: title, tagline, canonical URL, indexability, languages, and any extra <head> items you want injected on every page.' },
           { url: '/docs/core-reference/filters/',
             title: 'Filters',
             excerpt:
              'Eleventy filters Baseline registers. Some are always available; the rest come on with the module that registers them.' },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' },
           { url: '/docs/module/head/', title: 'head', excerpt: "INTERNAL_KEY: '_head'" },
           { url: '/docs/module/multilang/',
             title: 'multilang',
             excerpt: "INTERNAL_KEY: '_multilang'" },
           { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" },
           ... 1 more item ],
        '/docs/core-reference/filters/':
         [ { url: '/release-notes/',
             title: 'Release notes',
             excerpt:
              'Baseline ships on a rolling release cadence (0.1.0-next.X). Things shift, break, and get renamed between releases. Pin a version when you build something serious on top.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/tutorial/multilingual-baseline-site/',
             title: 'Build a multilingual site',
             excerpt:
              "Add a second language to a Baseline site, with everything you'd expect: per-language URLs, hreflang on every page, a sitemap for each language plus an index." },
           { url: '/docs/feature-guide/assets-pipeline/',
             title: 'Assets pipeline quickstart',
             excerpt:
              "Ship CSS and JS through Baseline's assets module. By the end you'll have one CSS entry going through PostCSS, one JS entry going through esbuild, and a handle on the inline filters when you need them." },
           { url: '/docs/feature-guide/debugging-navigator/',
             title: 'Debugging with Navigator',
             excerpt:
              "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." },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/module/assets/', title: 'assets', excerpt: "INTERNAL_KEY: '_assets'" },
           { url: '/docs/module/multilang/',
             title: 'multilang',
             excerpt: "INTERNAL_KEY: '_multilang'" },
           { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" } ],
        '/docs/introduction/':
         [ { url: '/docs/',
             title: 'Documentation',
             excerpt: 'The documentation for Baseline. Each chapter with its own job:' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' } ],
        '/docs/concept/':
         [ { url: '/docs/',
             title: 'Documentation',
             excerpt: 'The documentation for Baseline. Each chapter with its own job:' },
           { url: '/docs/introduction/',
             title: 'Introduction',
             excerpt:
              'Start here. The overview is what Baseline is and whether it is for you. The quickstart gets you a running site.' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/introduction/quickstart/',
             title: 'Quickstart',
             excerpt:
              'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.' } ],
        '/docs/tutorial/':
         [ { url: '/docs/',
             title: 'Documentation',
             excerpt: 'The documentation for Baseline. Each chapter with its own job:' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' } ],
        '/docs/how-to/':
         [ { url: '/docs/',
             title: 'Documentation',
             excerpt: 'The documentation for Baseline. Each chapter with its own job:' } ],
        '/docs/core-reference/':
         [ { url: '/docs/',
             title: 'Documentation',
             excerpt: 'The documentation for Baseline. Each chapter with its own job:' },
           { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' } ],
        '/docs/module/':
         [ { url: '/docs/',
             title: 'Documentation',
             excerpt: 'The documentation for Baseline. Each chapter with its own job:' },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' } ],
        '/docs/module/assets/':
         [ { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/feature-guide/assets-pipeline/',
             title: 'Assets pipeline quickstart',
             excerpt:
              "Ship CSS and JS through Baseline's assets module. By the end you'll have one CSS entry going through PostCSS, one JS entry going through esbuild, and a handle on the inline filters when you need them." },
           { url: '/docs/how-to/customise-assets-pipeline/',
             title: 'Customise the Assets Pipeline',
             excerpt:
              'When the fallback configs in the assets module are not enough, drop your own in. PostCSS for CSS, esbuild for JS. The module picks them up.' },
           { url: '/docs/how-to/integrate-eleventy-base-blog/',
             title: 'Integrate with Eleventy Base Blog',
             excerpt: 'This article is planned for revision, its content might be stale.' },
           { url: '/docs/core-reference/filters/',
             title: 'Filters',
             excerpt:
              'Eleventy filters Baseline registers. Some are always available; the rest come on with the module that registers them.' },
           { url: '/docs/core-reference/image-shortcode/',
             title: 'Image shortcode',
             excerpt:
              "The shortcode is Baseline's; the underlying engine is @11ty/eleventy-img. The two halves split cleanly:" },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' },
           { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" } ],
        '/docs/module/sitemap/':
         [ { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/feature-guide/sitemaps-and-drafts/',
             title: 'Sitemaps and Drafts',
             excerpt:
              "Control which pages end up in your sitemap, and let work-in-progress pages live alongside published ones without leaking into production. By the end you'll have per-page sitemap controls, a working noindex story, and a draft workflow that behaves differently in dev and build, the way you'd want." },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' },
           { url: '/docs/module/multilang/',
             title: 'multilang',
             excerpt: "INTERNAL_KEY: '_multilang'" },
           { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" } ],
        '/docs/core-reference/page-context/':
         [ { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/concept/content-organisation/',
             title: 'Content organisation',
             excerpt: 'Every page on a Baseline site has two layers behind it.' },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/core-reference/site-settings/',
             title: 'Site settings',
             excerpt:
              'settings is the first argument to baseline(). It carries site identity: title, tagline, canonical URL, indexability, languages, and any extra <head> items you want injected on every page.' },
           { url: '/docs/core-reference/seo-graph/',
             title: 'SEO graph',
             excerpt:
              'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.' },
           { url: '/docs/core-reference/content-graph/',
             title: 'Content graph',
             excerpt:
              "A pre-rendered map of every page's headings, images, links, and excerpts, plus the links between pages. Built once before Eleventy's main build by a programmatic dry-run of the site; cached at .cache/_baseline/content-graph.json. Templates read it through cascade keys; modules read it through coreContext.runtime.contentGraph." },
           { url: '/docs/core-reference/internals/',
             title: 'Internals',
             excerpt:
              '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.' },
           { url: '/docs/core-reference/globals/',
             title: 'Globals',
             excerpt:
              'Baseline registers a handful of global data keys and a few Nunjucks globals. Most of them are reference targets you can read in templates; the rest are reserved namespaces that keep module-namespaced data from colliding with filters.' },
           ... 4 more items ],
        '/docs/core-reference/image-shortcode/':
         [ { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/feature-guide/image-shortcode-basics/',
             title: 'Image Shortcode Basics',
             excerpt: 'Render a responsive image with one line of template code.' },
           { url: '/docs/how-to/image-transform/',
             title: 'Image Transform',
             excerpt:
              "The image transform is eleventy-img's, not Baseline's. The two run side by side: eleventyImageTransformPlugin rewrites <img> and <picture> into responsive markup with generated assets and caching, and you add it to your config yourself." },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/module/assets/', title: 'assets', excerpt: "INTERNAL_KEY: '_assets'" } ],
        '/docs/concept/architecture-snapshot/':
         [ { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/introduction/quickstart/',
             title: 'Quickstart',
             excerpt:
              'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.' },
           { url: '/docs/concept/',
             title: 'Concept',
             excerpt:
              'The concept overview is the mental model behind the plugin. Project structure are the small set of rules that keep Baseline out of your way, and content organisation is the page-data pattern those rules assume.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/core-reference/content-graph/',
             title: 'Content graph',
             excerpt:
              "A pre-rendered map of every page's headings, images, links, and excerpts, plus the links between pages. Built once before Eleventy's main build by a programmatic dry-run of the site; cached at .cache/_baseline/content-graph.json. Templates read it through cascade keys; modules read it through coreContext.runtime.contentGraph." } ],
        '/docs/how-to/integrate-eleventy-base-blog/':
         [ { url: '/docs/introduction/overview/',
             title: 'Overview',
             excerpt:
              'Baseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.' },
           { url: '/docs/how-to/',
             title: "How-To's",
             excerpt:
              'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.' } ],
        '/docs/core-reference/config-export/':
         [ { url: '/docs/introduction/quickstart/',
             title: 'Quickstart',
             excerpt:
              'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/tutorial/simple-baseline-site/',
             title: 'Build a simple site',
             excerpt:
              "The shortest path from an empty folder to a working Baseline site. By the end you'll have a single page rendering through Eleventy, a tiny stylesheet bundled automatically, and a sitemap that updates itself." },
           { url: '/docs/feature-guide/deployment-url-checks/',
             title: 'Deployment URL Checks',
             excerpt:
              'Keep your URLs correct across dev, preview, and production, so canonicals, sitemap entries, and links never leak localhost to the live site. The mechanics are mostly Eleventy and environment variables; this chapter is the small set of habits that keep them honest.' },
           { url: '/docs/how-to/integrate-eleventy-base-blog/',
             title: 'Integrate with Eleventy Base Blog',
             excerpt: 'This article is planned for revision, its content might be stale.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/core-reference/internals/',
             title: 'Internals',
             excerpt:
              '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.' },
           { url: '/docs/core-reference/globals/',
             title: 'Globals',
             excerpt:
              'Baseline registers a handful of global data keys and a few Nunjucks globals. Most of them are reference targets you can read in templates; the rest are reserved namespaces that keep module-namespaced data from colliding with filters.' } ],
        '/docs/tutorial/multilingual-baseline-site/':
         [ { url: '/docs/introduction/quickstart/',
             title: 'Quickstart',
             excerpt:
              'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/tutorial/',
             title: 'Tutorials',
             excerpt:
              'These are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the feature guides chapter.' },
           { url: '/docs/feature-guide/head-and-noindex/',
             title: 'Head and NoIndex',
             excerpt:
              "Get a clean, correct <head> on every page with one placeholder and a settings file. By the end you'll have site-wide metadata, per-page head extras flowing through settings.head and front matter, and a proper canonical and robots story." },
           { url: '/docs/feature-guide/deployment-url-checks/',
             title: 'Deployment URL Checks',
             excerpt:
              'Keep your URLs correct across dev, preview, and production, so canonicals, sitemap entries, and links never leak localhost to the live site. The mechanics are mostly Eleventy and environment variables; this chapter is the small set of habits that keep them honest.' },
           { url: '/docs/how-to/multilingual-index/',
             title: 'Multilingual Index',
             excerpt:
              "A small index page that groups every page on the site by language. Useful when you have a multilingual site and want a single landing point that fans out to each language's content." },
           { url: '/docs/module/multilang/',
             title: 'multilang',
             excerpt: "INTERNAL_KEY: '_multilang'" } ],
        '/docs/feature-guide/head-and-noindex/':
         [ { url: '/docs/introduction/quickstart/',
             title: 'Quickstart',
             excerpt:
              'The minimum working setup. A checklist; for a guided walk with reasoning, see the simple-site tutorial.' },
           { url: '/docs/tutorial/simple-baseline-site/',
             title: 'Build a simple site',
             excerpt:
              "The shortest path from an empty folder to a working Baseline site. By the end you'll have a single page rendering through Eleventy, a tiny stylesheet bundled automatically, and a sitemap that updates itself." },
           { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." },
           { url: '/docs/module/head/', title: 'head', excerpt: "INTERNAL_KEY: '_head'" } ],
        '/docs/concept/concept-overview/':
         [ { url: '/docs/concept/',
             title: 'Concept',
             excerpt:
              'The concept overview is the mental model behind the plugin. Project structure are the small set of rules that keep Baseline out of your way, and content organisation is the page-data pattern those rules assume.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/module/',
             title: 'Modules',
             excerpt:
              'Baseline ships as five feature modules. Each one wires a distinct concern into Eleventy and stays out of the way of the others. The pages below cover what each module does, when it activates, and the options it accepts.' } ],
        '/docs/concept/project-structure/':
         [ { url: '/docs/concept/',
             title: 'Concept',
             excerpt:
              'The concept overview is the mental model behind the plugin. Project structure are the small set of rules that keep Baseline out of your way, and content organisation is the page-data pattern those rules assume.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/concept/content-organisation/',
             title: 'Content organisation',
             excerpt: 'Every page on a Baseline site has two layers behind it.' } ],
        '/docs/concept/content-organisation/':
         [ { url: '/docs/concept/',
             title: 'Concept',
             excerpt:
              'The concept overview is the mental model behind the plugin. Project structure are the small set of rules that keep Baseline out of your way, and content organisation is the page-data pattern those rules assume.' },
           { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' } ],
        '/docs/concept/content-helpers/':
         [ { url: '/docs/concept/',
             title: 'Concept',
             excerpt:
              'The concept overview is the mental model behind the plugin. Project structure are the small set of rules that keep Baseline out of your way, and content organisation is the page-data pattern those rules assume.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' } ],
        '/docs/core-reference/plugin-entrypoint/':
         [ { url: '/docs/concept/concept-overview/',
             title: 'Concept overview',
             excerpt:
              'Baseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.' },
           { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' },
           { url: '/docs/how-to/deploy-under-a-subpath/',
             title: 'Deploy Under a Subpath',
             excerpt:
              'Serve a Baseline site from a subpath like /docs/ without breaking links, asset paths, canonical URLs, or the sitemap on the way.' },
           { url: '/docs/how-to/multilingual-index/',
             title: 'Multilingual Index',
             excerpt:
              "A small index page that groups every page on the site by language. Useful when you have a multilingual site and want a single landing point that fans out to each language's content." },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/site-settings/',
             title: 'Site settings',
             excerpt:
              'settings is the first argument to baseline(). It carries site identity: title, tagline, canonical URL, indexability, languages, and any extra <head> items you want injected on every page.' },
           { url: '/docs/core-reference/config-export/',
             title: 'Config export',
             excerpt:
              "Baseline ships a directory contract as a named export. Eleventy's modules expect specific input, output, includes, and data folders; Baseline's modules expect two more (assets, public)." },
           { url: '/docs/core-reference/filters/',
             title: 'Filters',
             excerpt:
              'Eleventy filters Baseline registers. Some are always available; the rest come on with the module that registers them.' },
           { url: '/docs/core-reference/globals/',
             title: 'Globals',
             excerpt:
              'Baseline registers a handful of global data keys and a few Nunjucks globals. Most of them are reference targets you can read in templates; the rest are reserved namespaces that keep module-namespaced data from colliding with filters.' },
           ... 1 more item ],
        '/docs/how-to/customise-assets-pipeline/':
         [ { url: '/docs/concept/project-structure/',
             title: 'Project structure',
             excerpt:
              "The folder structure that keeps Baseline out of your way. If you've read the overview and the concept overview, you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own." },
           { url: '/docs/how-to/',
             title: "How-To's",
             excerpt:
              'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.' },
           { url: '/docs/module/assets/', title: 'assets', excerpt: "INTERNAL_KEY: '_assets'" } ],
        '/docs/how-to/image-transform/':
         [ { url: '/docs/concept/content-helpers/',
             title: 'Content helpers',
             excerpt:
              'This section covers the small but important pieces that keep content predictable as it scales.' },
           { url: '/docs/how-to/',
             title: "How-To's",
             excerpt:
              'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.' } ],
        '/docs/core-reference/internals/':
         [ { url: '/docs/concept/architecture-snapshot/',
             title: 'Architecture snapshot',
             excerpt: 'The plugin is built in three concentric layers, each with one strict job.' },
           { url: '/docs/core-reference/',
             title: 'Core reference',
             excerpt:
              'The inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.' },
           { url: '/docs/core-reference/plugin-entrypoint/',
             title: 'Plugin entrypoint',
             excerpt:
              'The baseline() factory is the single entry point. You call it once in your Eleventy config callback with two arguments: site settings and module options. Everything below is what that call sets up.' },
           { url: '/docs/core-reference/config-export/',
             title: 'Config export',
             excerpt:
              "Baseline ships a directory contract as a named export. Eleventy's modules expect specific input, output, includes, and data folders; Baseline's modules expect two more (assets, public)." },
           { url: '/docs/core-reference/page-context/',
             title: 'Page context',
             excerpt:
              "A normalised per-page object: one cached snapshot of the values Baseline's modules need, built once during the data cascade and read again at transform-time without re-deriving from raw cascade data." },
           { url: '/docs/core-reference/seo-graph/',
             title: 'SEO graph',
             excerpt:
              'A resolved per-page object: the canonical URL, the Open Graph and Twitter projections, and a JSON-LD @graph. Built once during the data cascade, cached, and read again at transform-time when the head module emits the tags.' },
           { url: '/docs/core-reference/globals/',
             title: 'Globals',
             excerpt:
              'Baseline registers a handful of global data keys and a few Nunjucks globals. Most of them are reference targets you can read in templates; the rest are reserved namespaces that keep module-namespaced data from colliding with filters.' },
           { url: '/docs/module/head/', title: 'head', excerpt: "INTERNAL_KEY: '_head'" },
           { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" } ],
        '/docs/feature-guide/':
         [ { url: '/docs/tutorial/',
             title: 'Tutorials',
             excerpt:
              'These are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the feature guides chapter.' } ],
        '/docs/feature-guide/assets-pipeline/':
         [ { url: '/docs/tutorial/simple-baseline-site/',
             title: 'Build a simple site',
             excerpt:
              "The shortest path from an empty folder to a working Baseline site. By the end you'll have a single page rendering through Eleventy, a tiny stylesheet bundled automatically, and a sitemap that updates itself." },
           { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." },
           { url: '/docs/module/assets/', title: 'assets', excerpt: "INTERNAL_KEY: '_assets'" } ],
        '/docs/feature-guide/image-shortcode-basics/':
         [ { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." } ],
        '/docs/feature-guide/sitemaps-and-drafts/':
         [ { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." },
           { url: '/docs/feature-guide/debugging-navigator/',
             title: 'Debugging with Navigator',
             excerpt:
              "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." },
           { url: '/docs/module/sitemap/',
             title: 'sitemap',
             excerpt: "INTERNAL_KEY: '_sitemap'" } ],
        '/docs/feature-guide/deployment-url-checks/':
         [ { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." },
           { url: '/docs/how-to/deploy-under-a-subpath/',
             title: 'Deploy Under a Subpath',
             excerpt:
              'Serve a Baseline site from a subpath like /docs/ without breaking links, asset paths, canonical URLs, or the sitemap on the way.' },
           { url: '/docs/how-to/build-scripts-and-cleanup/',
             title: 'Build Scripts and Cleanup',
             excerpt:
              `A small set of npm scripts that take Baseline's dev and build commands from "works on my machine" to predictable across platforms. Three helpers do the work: rimraf for cleanup, npm-run-all for sequencing, and cross-env for portable env vars.` } ],
        '/docs/feature-guide/debugging-navigator/':
         [ { url: '/docs/feature-guide/',
             title: 'Feature guides',
             excerpt:
              "These feature tutorials build on each other. Starting from the simple site; you'll fill it in with assets, images, and head extras, then publish it through sitemaps and deployment. Debugging comes last, as the tool you reach for when something is off." },
           { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" } ],
        '/docs/how-to/deploy-under-a-subpath/':
         [ { url: '/docs/feature-guide/deployment-url-checks/',
             title: 'Deployment URL Checks',
             excerpt:
              'Keep your URLs correct across dev, preview, and production, so canonicals, sitemap entries, and links never leak localhost to the live site. The mechanics are mostly Eleventy and environment variables; this chapter is the small set of habits that keep them honest.' },
           { url: '/docs/how-to/',
             title: "How-To's",
             excerpt:
              'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.' } ],
        '/docs/how-to/multilingual-index/':
         [ { url: '/docs/how-to/',
             title: "How-To's",
             excerpt:
              'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.' },
           { url: '/docs/module/multilang/',
             title: 'multilang',
             excerpt: "INTERNAL_KEY: '_multilang'" } ],
        '/docs/how-to/build-scripts-and-cleanup/':
         [ { url: '/docs/how-to/',
             title: "How-To's",
             excerpt:
              'Recipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.' },
           { url: '/docs/how-to/deploy-under-a-subpath/',
             title: 'Deploy Under a Subpath',
             excerpt:
              'Serve a Baseline site from a subpath like /docs/ without breaking links, asset paths, canonical URLs, or the sitemap on the way.' },
           { url: '/docs/how-to/integrate-eleventy-base-blog/',
             title: 'Integrate with Eleventy Base Blog',
             excerpt: 'This article is planned for revision, its content might be stale.' } ],
        '/docs/core-reference/internals/_baseline/core/registry.js':
         [ { url: '/docs/core-reference/internals/',
             title: 'Internals',
             excerpt:
              '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.' } ],
        '/docs/module/assets/_baseline/modules/assets/processors/esbuild-process.js':
         [ { url: '/docs/module/assets/', title: 'assets', excerpt: "INTERNAL_KEY: '_assets'" } ],
        '/docs/module/multilang/_baseline/core/utils/normalize-language-map.js':
         [ { url: '/docs/module/multilang/',
             title: 'multilang',
             excerpt: "INTERNAL_KEY: '_multilang'" } ],
        '/navigator-core.html':
         [ { url: '/docs/module/navigator/',
             title: 'navigator',
             excerpt: "INTERNAL_KEY: '_navigator'" },
           { url: '/navigator-core.html', title: 'Navigator Core', excerpt: '← Go back' } ],
        '/docs/module/sitemap/_baseline/core/utils/normalize-languages.js':
         [ { url: '/docs/module/sitemap/',
             title: 'sitemap',
             excerpt: "INTERNAL_KEY: '_sitemap'" } ] } },
  _sitemap: {},
  _snapshot:
   { contentMap: null,
     pageContext:
      { '/navigator-core.html':
         { site:
            { title: 'Eleventy Baseline',
              tagline: 'Start building your site and skip the recurring setup work.',
              description: '',
              url: 'https://www.eleventy-baseline.dev',
              noindex: false },
           page:
            { inputPath: './src/navigator-core.html',
              fileSlug: 'navigator-core',
              filePathStem: '/navigator-core',
              outputFileExtension: 'html',
              templateSyntax: 'njk',
              date: 2026-06-08T15:47:32.302Z,
              url: '/navigator-core.html',
              outputPath: './dist/navigator-core.html',
              lang: 'en',
              locale: 'en',
              translationKey: undefined,
              isDefaultLang: true,
              sitemap: [Object] },
           entry:
            { title: 'Navigator Core',
              description: 'Eleventy + Baseline internals',
              excerpt: undefined,
              slug: 'navigator-core',
              section: undefined,
              type: undefined,
              head: undefined,
              breadcrumbs: [] },
           query: { isHome: false },
           meta:
            { title: 'Navigator Core | Eleventy Baseline',
              description: 'Eleventy + Baseline internals',
              canonical: 'https://www.eleventy-baseline.dev/navigator-core.html',
              robots: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1',
              noindex: false },
           render: { generator: 'Eleventy v3.1.5' },
           head: { link: [Array], script: [Array], style: [], meta: [Array] } } },
     seoGraph:
      { '/navigator-core.html':
         { url: 'https://www.eleventy-baseline.dev/navigator-core.html',
           schema: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
           openGraph:
            { title: 'Navigator Core',
              type: 'website',
              url: 'https://www.eleventy-baseline.dev/navigator-core.html',
              locale: 'en',
              description: 'Eleventy + Baseline internals',
              siteName: 'Eleventy Baseline',
              image: 'https://www.eleventy-baseline.dev/og.jpg',
              imageAlt: 'Eleventy Baseline',
              imageWidth: 1200,
              imageHeight: 630 },
           twitter: { card: 'summary_large_image' } } } },
  eleventyComputed:
   { _pageContext: [Function (anonymous)],
     _seoGraph: [Function (anonymous)],
     _node: [Function (anonymous)],
     _backlinks: [Function (anonymous)],
     _outgoing: [Function (anonymous)],
     page:
      { lang: [Function (anonymous)],
        locale: [Function (anonymous)],
        translationKey: [Function (anonymous)],
        isDefaultLang: [Function (anonymous)],
        sitemap: [Function (anonymous)] },
     _snapshot: [Function (anonymous)] },
  eleventy:
   { version: '3.1.5',
     generator: 'Eleventy v3.1.5',
     env:
      { source: 'cli',
        runMode: 'build',
        config: '/opt/build/repo/eleventy.config.js',
        root: '/opt/build/repo' },
     directories:
      { input: './src/',
        inputFile: undefined,
        inputGlob: undefined,
        data: './src/_data/',
        includes: './src/_includes/',
        layouts: undefined,
        output: './dist/' } },
  pkg:
   { name: 'eleventy-baseline-docs',
     version: '1.0.0',
     description: 'An experimental Swiss army knife toolkit for Eleventy',
     main: 'index.js',
     type: 'module',
     engines: { node: '>=20' },
     scripts:
      { test: 'vitest run',
        start: 'npm-run-all clean dev',
        'start-next': 'npm-run-all clean dev-next',
        clean: 'rimraf dist/',
        dev: 'npx @11ty/eleventy --serve',
        'dev-next': 'npx @11ty/eleventy --config=eleventy.config.next.js --serve',
        build: 'npm-run-all clean build:eleventy',
        'build-next': 'npm-run-all clean build:eleventy-next',
        'build:eleventy': 'cross-env ELEVENTY_ENV=production npx @11ty/eleventy',
        'build:eleventy-next':
         'cross-env ELEVENTY_ENV=production npx @11ty/eleventy --config=eleventy.config.next.js',
        dryrun: 'npx @11ty/eleventy --dryrun',
        'dryrun:prod': 'cross-env ELEVENTY_ENV=production npx @11ty/eleventy --dryrun',
        'dryrun:next': 'npx @11ty/eleventy --config=eleventy.config.next.js --dryrun',
        debug: 'npm-run-all clean debug:*',
        'debug:log': 'npm-run-all clean debug:eleventy-logged',
        'debug:eleventy': 'cross-env DEBUG=Eleventy* npx @11ty/eleventy --dryrun',
        'debug:eleventy-logged': 'cross-env DEBUG=Eleventy* npx @11ty/eleventy --dryrun > debug.log 2>&1',
        lint: 'eslint . --ext=js,jsx,ts,tsx',
        'lint:fix': 'eslint . --ext=js,jsx,ts,tsx --fix',
        'lint:docs': 'eslint . --ignore-pattern "_baseline/" --ext=js,jsx,ts,tsx',
        'lint:docs-fix': 'eslint . --ignore-pattern "_baseline/" --ext=js,jsx,ts,tsx --fix',
        'lint:plugin': 'eslint _baseline/ --ext=js,jsx,ts,tsx',
        'lint:plugin-fix': 'eslint _baseline/ --ext=js,jsx,ts,tsx --fix',
        'format:docs': 'prettier . "!_baseline/**/*" --check',
        'format:docs-fix': 'prettier . "!_baseline/**/*" --write',
        'format:plugin': 'prettier ./_baseline --check --debug-check',
        'format:plugin-fix': 'prettier ./_baseline --write',
        baseline: 'npx @11ty/eleventy --config _baseline/eleventy.config.js --serve',
        release: 'bash _baseline/release.sh',
        'release:tag': 'bash _baseline/release.sh tag',
        'release:local': 'bash _baseline/release.sh local' },
     author: 'Cristovao Verstraeten',
     license: 'ISC',
     keywords: [ 'eleventy-plugin', 'eleventy' ],
     repository:
      { url: 'git@github.com:apleasantview/eleventy-plugin-baseline.git', type: 'git' },
     private: true,
     dependencies:
      { '@11ty/eleventy': '3.1.5',
        '@11ty/eleventy-img': '^6.0.4',
        '@11ty/eleventy-plugin-syntaxhighlight': '^5.0.2',
        '@jdevalk/seo-graph-core': '^0.6.2',
        '@rviscomi/capo.js': '^2.1.0',
        'cross-env': '^10.1.0',
        cssnano: '^7.1.3',
        dotenv: '^17.3.1',
        esbuild: '0.27.4',
        linkedom: '^0.18.12',
        'markdown-it-attrs': '^4.3.1',
        'npm-run-all': '^4.1.5',
        postcss: '^8.5.8',
        'postcss-import': '^16.1.1',
        'postcss-import-ext-glob': '^2.1.1',
        'postcss-load-config': '^6.0.1',
        'postcss-preset-env': '^11.2.0',
        prismjs: '^1.30.0',
        rimraf: '^6.1.3',
        zod: '^4.3.6' },
     devDependencies:
      { '@eslint/js': '^10.0.1',
        '@vitest/coverage-v8': '^4.1.4',
        eslint: '^10.1.0',
        globals: '^17.6.0',
        prettier: '^3.8.1',
        'prettier-plugin-jinja-template': '^2.1.0',
        sharp: '^0.34.5',
        vitest: '^4.1.4' } },
  title: 'Navigator Core',
  permalink: '/navigator-core.html',
  description: 'Eleventy + Baseline internals',
  layout: null,
  eleventyExcludeFromCollections: true,
  _internal: false,
  inspectorDepth: 4,
  page:
   { inputPath: './src/navigator-core.html',
     fileSlug: 'navigator-core',
     filePathStem: '/navigator-core',
     outputFileExtension: 'html',
     templateSyntax: 'njk',
     date: 2026-06-08T15:47:32.302Z,
     rawInput:
      '\n<!DOCTYPE html>\n<html lang="{{ lang | default(settings.defaultLanguage) }}">\n\n<head>\n\t<baseline-head></baseline-head>\n\t<style>\n\t\t._navigator__wrapper:not(#\\#):not(#\\#) {\n\t\t\tbox-sizing: content-box;\n\t\t\tmax-width: 60rem;\n\t\t\tpadding-inline: clamp(1rem, 0.2083rem + 3.5185vw, 3.375rem);\n\t\t\tmargin-inline: auto;\n\t\t}\n\n\t\t._navigator__wrapper:not(#\\#):not(#\\#) > * + * {\n\t\t\tmargin-block-start: 1.25rem;\n\t\t}\n\t</style>\n</head>\n\n<body>\n\t<a href="#main" class="skip-link">\n\t\tSkip to main content\n\t</a>\n\t<header>\n\t\t<div class="_navigator__wrapper">\n\t\t\t<h1>{{ settings.title }} Navigator</h1>\n\t\t\t<div>\n\t\t\t\t<p>{{ settings.tagline }}</p>\n\t\t\t</div>\n\t\t</div>\n\t</header>\n\t<main id="main" tabindex="-1">\n\t\t<div class="_navigator__wrapper">\n\t\t\t<p><a id="go-back" href=""><span style="vertical-align: text-bottom;">&#8592;</span>&nbsp;Go back</a></p>\n\t\t\t<h2><u>Navigator</u></h2>\n\t\t\t<details>\n\t\t\t\t<summary><strong>Page Context</strong></summary>\n\t\t\t\t<pre>\n\t\t\t\t\t{{- _pageContext | _inspect({ depth: null }) -}}\n\t\t\t\t</pre>\n\t\t\t</details>\n\t\t\t{% for key, value in _runtime() %}\n\t\t\t<details>\n\t\t\t\t<summary><strong>{{ key }}</strong></summary>\n\t\t\t\t{% if value | isString %}\n\t\t\t\t<pre>{{ value }}</pre>\n\t\t\t\t{% else %}\n\t\t\t\t<pre>{{ value | _inspect({ depth: inspectorDepth }) }}</pre>\n\t\t\t\t{% endif %}\n\t\t\t</details>\n\t\t\t{% endfor %}\n\t\t</div>\n\t</main>\n\t<script>\n\t\tdocument.getElementById("go-back").addEventListener("click", (event) => {\n\t\t\tevent.preventDefault();\n\t\t\thistory.back();\n\t\t});\n\t</script>\n\t<footer>\n\t\t<div class="_navigator__wrapper"><small>Navigator Core — Eleventy Plugin Baseline</small></div>\n\t</footer>\n</body>\n\n</html>\n',
     url: '/navigator-core.html',
     outputPath: './dist/navigator-core.html',
     lang: 'en',
     locale: 'en',
     translationKey: undefined,
     isDefaultLang: true,
     sitemap: { ignore: false, changefreq: '', priority: -1 } },
  collections:
   <ref *1> {
     docs:
      [ { template:
           Template {
             inputPath: './src/content/docs/00.index.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '00.index',
             filePathStem: '/content/docs/00.index',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThe documentation for Baseline. Each chapter with its own job:\n\n- **[[introduction]]**: what Baseline is, who it is for and a quickstart.\n- **[[concept]]**: The mental model, community-seeded conventions and a snapshot of the inner workings.\n- **[[tutorial]]**: guided walks through real builds, end to end.\n- **[[how-to]]**: task-oriented recipes for specific problems.\n- **[[core-reference]]**: exact details of what the plugin registers. Options, filters, globals, the image shortcode, the page context, internals.\n- **[[module]]**: per-module reference for the five feature modules (assets, head, multilang, navigator, sitemap).\n\n## Where to start\n\nIf Baseline is new to you, the [[introduction | introduction]] is the door. If you already know the plugin and want a specific detail, the [[core-reference | core reference]] and [[module | modules]] chapters are the lookup view.\n\n## About this project\n\nPackage: `@apleasantview/eleventy-plugin-baseline` on [npm](https://www.npmjs.com/package/@apleasantview/eleventy-plugin-baseline). Source on [GitHub](https://github.com/apleasantview/eleventy-plugin-baseline).\n\nBaseline is in active development, published under `0.1.0-next.X` semver. APIs and defaults may shift between releases.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: '/docs/',
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             title: 'Documentation',
             slug: 'docs',
             description:
              'Documentation for the Eleventy Baseline plugin: introduction, tutorials, how-tos, references, and module pages.',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/00.index.md',
             fileSlug: '00.index',
             filePathStem: '/content/docs/00.index',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              '\nThe documentation for Baseline. Each chapter with its own job:\n\n- **[[introduction]]**: what Baseline is, who it is for and a quickstart.\n- **[[concept]]**: The mental model, community-seeded conventions and a snapshot of the inner workings.\n- **[[tutorial]]**: guided walks through real builds, end to end.\n- **[[how-to]]**: task-oriented recipes for specific problems.\n- **[[core-reference]]**: exact details of what the plugin registers. Options, filters, globals, the image shortcode, the page context, internals.\n- **[[module]]**: per-module reference for the five feature modules (assets, head, multilang, navigator, sitemap).\n\n## Where to start\n\nIf Baseline is new to you, the [[introduction | introduction]] is the door. If you already know the plugin and want a specific detail, the [[core-reference | core reference]] and [[module | modules]] chapters are the lookup view.\n\n## About this project\n\nPackage: `@apleasantview/eleventy-plugin-baseline` on [npm](https://www.npmjs.com/package/@apleasantview/eleventy-plugin-baseline). Source on [GitHub](https://github.com/apleasantview/eleventy-plugin-baseline).\n\nBaseline is in active development, published under `0.1.0-next.X` semver. APIs and defaults may shift between releases.\n',
             url: '/docs/',
             outputPath: './dist/docs/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-05-13T14:34:22.000Z },
          inputPath: './src/content/docs/00.index.md',
          fileSlug: '00.index',
          filePathStem: '/content/docs/00.index',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/index.html',
          url: '/docs/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/00.introduction/00.index.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '00.index',
             filePathStem: '/content/docs/00.introduction/00.index',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nStart here. The [[overview | overview]] is what Baseline is and whether it is for you. The [[quickstart | quickstart]] gets you a running site.\n\nFrom there, the [[concept | concept chapter]] has the mental model behind the plugin and the small set of rules that keep Baseline out of your way.\n\n---\n\n## In this chapter\n\n{% include "partials/chapter-toc.njk" %}\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: '/docs/introduction/',
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Introduction',
             title: 'Introduction',
             description:
              'Start here: what Baseline is, who it is for, the mental model, and a quickstart.',
             slug: 'introduction',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/00.introduction/00.index.md',
             fileSlug: '00.index',
             filePathStem: '/content/docs/00.introduction/00.index',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              '\nStart here. The [[overview | overview]] is what Baseline is and whether it is for you. The [[quickstart | quickstart]] gets you a running site.\n\nFrom there, the [[concept | concept chapter]] has the mental model behind the plugin and the small set of rules that keep Baseline out of your way.\n\n---\n\n## In this chapter\n\n{% include "partials/chapter-toc.njk" %}\n',
             url: '/docs/introduction/',
             outputPath: './dist/docs/introduction/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-06-04T00:42:58.000Z },
          inputPath: './src/content/docs/00.introduction/00.index.md',
          fileSlug: '00.index',
          filePathStem: '/content/docs/00.introduction/00.index',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/introduction/index.html',
          url: '/docs/introduction/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/00.introduction/01.overview.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '01.overview',
             filePathStem: '/content/docs/00.introduction/01.overview',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\n## What Baseline is\n\nBaseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.\n\nEleventy hands you a content pipeline and gets out of your way.\n\nThat is the appeal, and also the reason every site you build with it ends up needing the same wiring underneath: directory layout, an asset pipeline, image handling, head tags, sitemap, language routing.\n\nNone of it is hard. You just write it again every time.\n\n---\n\n## A cohesive plugin system\n\nThe usual ways out are starter repos that fork once and rot, or stacks of single-purpose plugins that do not know about each other and tend to fight at the edges.\n\nBaseline handles the infrastructure layer, specifically the parts that fit together. The plugin is shaped in three layers:\n\n- **State** is your settings and options, normalised once at startup.\n- **Runtime**: state in motion, plus a per-page context and a registry that lets the modules read what they need without reaching across to each other.\n- **Modules** are the five feature plugins, self-contained slices of behaviour backed by the runtime.\n\nYour layouts in `_includes/`, your content and data in `content/` and `_data/`, your styles and scripts in `assets/`, and any plugins or filters you add yourself, all stay yours.\n\n---\n\n### Who this is for\n\nBaseline is written for someone who has built a handful of Eleventy sites and caught themselves wiring up the same things every time. You want those decisions made together, so they fit.\n\nYou still want to own your templates, content, and design. You would rather start from a working Baseline than a blank slate, or a starter repo that forks once and goes stale.\n\nIt is probably not for you if you already have a setup you like. Baseline does not replace what works; it replaces the third or fourth time you would set the same thing up from scratch.\n\nIt is also not for you if you want a full framework that owns layout and content as well. Baseline is deliberately smaller than that.\n\n---\n\n### Why a plugin?\n\nRecipes drift. Starter repos fork once and rot. Frameworks impose more than they solve.\n\nInstead of hunting through six tutorials and reconciling them by hand each time if Eleventy defaults changes or patterns shift, you get the new version of Baseline on `npm install`.\n\n---\n\n## What the Baseline modules do\n\nFive modules, each wiring a distinct concern into Eleventy:\n\n{% stepsBlock "compact" %}\n\n- **[[assets]]**: the asset pipeline. One CSS entry point per directory through PostCSS, one JS entry point through esbuild, and inline filters (`inlinePostCSS`, `inlineESbuild`) for critical-path CSS or JS.\n- **[[head]]**: a `<baseline-head>` placeholder that gets replaced with a sorted, deduped element list. Charset, viewport, title, description, robots, canonical, hreflang, plus the SEO payload (Open Graph, Twitter, JSON-LD). You drop the placeholder in your layout once.\n- **[[multilang]]**: directory-based multilingual support. Per-language collections, hreflang, a translation map, and the standard i18n filters (it wraps Eleventy\'s `I18nPlugin`). Opt-in.\n- **[[navigator]]**: runtime-introspection surface and public read surface. A `phpinfo()`-style virtual page that dumps current build state (on in development by default), the globals and filters used to build it, and the `_navigator` global (`{ nodes, edges, backlinks }`) for cross-page reads of the content graph.\n- **[[sitemap]]**: an XML sitemap. Every page is included unless you exclude it. When `multilang` is active, you get per-language sitemaps plus an index.\n\n{% endstepsBlock %}\n\nThreading the modules together is **page context** at `_pageContext`: a normalised per-page object the head, multilang, and sitemap modules all read from internally. Your templates can read it too. See the [[page-context | page context reference]].\n\n---\n\n## Baseline content helpers\n\nAlongside the modules, Baseline registers a small set of additions the moment you load it. These are always on because they are too small to be worth opting in or out of:\n\n{% stepsBlock "compact" %}\n\n- **Filters**: `markdownify`, `relatedPosts`, `isString`. See the [[filters | filters reference]].\n- **Globals**: a date-formatting helper, plus the `_baseline` data tree (`env`, `features`, `paths`) that templates can read at any time. See the [[globals | globals reference]].\n- **An [[image-shortcode | image shortcode]]** built on top of [eleventy-img](https://www.11ty.dev/docs/plugins/image/): AVIF and WebP, responsive widths, lazy loading. Alt text is required; the build warns if you skip it.\n\n{% endstepsBlock %}\n\nAnd three behaviours that need no configuration at all:\n\n{% stepsBlock "compact" %}\n\n- A **drafts preprocessor**: any template with `draft: true` in front matter is excluded from production builds.\n- A **dev image pipeline**: `eleventy-img` is wired up for in-flight transforms during `--serve`.\n- **Passthrough copy** for the `static/` directory: anything in there is copied to the site root as-is.\n\n{% endstepsBlock %}\n\nThe full surface lives in the [[core-reference | core reference]] chapter.\n\n---\n\n## Stability and scope\n\nBaseline is in active development. Versions ship as `0.1.0-next.X` and that is a deliberate signal: things may shift between releases, and you should pin a version when you build something serious on top.\n\nThe five modules above are the supported surface today. The head module also emits a full SEO payload: canonical, Open Graph, Twitter cards, and a JSON-LD graph, configured through `settings.seo` and per-page front matter.\n\nIf something in the docs claims a behaviour you cannot reproduce, the docs are probably wrong. Please [open an issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\n---\n\n## Where to go next\n\n- The [[concept | concept]] chapter for the mental model and community-seeded conventions.\n- The [[quickstart | quickstart]] for a checklist that gets you a running site.\n- The [[simple-baseline-site | simple-site]] tutorial for a guided walk through the same checklist with reasoning.\n- The [[architecture-snapshot | architecture snapshot]] for a deeper look at the three layers if you want it.\n\nAlready have an Eleventy site you want to graft Baseline onto? See [[integrate-eleventy-base-blog]].\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Introduction',
             title: 'Overview',
             description:
              'What Baseline is, who it is for, why it is a plugin, and what it gives you out of the box.',
             slug: 'overview',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/00.introduction/01.overview.md',
             fileSlug: '01.overview',
             filePathStem: '/content/docs/00.introduction/01.overview',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              '\n## What Baseline is\n\nBaseline is an Eleventy plugin that handles the scaffolding every Eleventy site ends up needing.\n\nEleventy hands you a content pipeline and gets out of your way.\n\nThat is the appeal, and also the reason every site you build with it ends up needing the same wiring underneath: directory layout, an asset pipeline, image handling, head tags, sitemap, language routing.\n\nNone of it is hard. You just write it again every time.\n\n---\n\n## A cohesive plugin system\n\nThe usual ways out are starter repos that fork once and rot, or stacks of single-purpose plugins that do not know about each other and tend to fight at the edges.\n\nBaseline handles the infrastructure layer, specifically the parts that fit together. The plugin is shaped in three layers:\n\n- **State** is your settings and options, normalised once at startup.\n- **Runtime**: state in motion, plus a per-page context and a registry that lets the modules read what they need without reaching across to each other.\n- **Modules** are the five feature plugins, self-contained slices of behaviour backed by the runtime.\n\nYour layouts in `_includes/`, your content and data in `content/` and `_data/`, your styles and scripts in `assets/`, and any plugins or filters you add yourself, all stay yours.\n\n---\n\n### Who this is for\n\nBaseline is written for someone who has built a handful of Eleventy sites and caught themselves wiring up the same things every time. You want those decisions made together, so they fit.\n\nYou still want to own your templates, content, and design. You would rather start from a working Baseline than a blank slate, or a starter repo that forks once and goes stale.\n\nIt is probably not for you if you already have a setup you like. Baseline does not replace what works; it replaces the third or fourth time you would set the same thing up from scratch.\n\nIt is also not for you if you want a full framework that owns layout and content as well. Baseline is deliberately smaller than that.\n\n---\n\n### Why a plugin?\n\nRecipes drift. Starter repos fork once and rot. Frameworks impose more than they solve.\n\nInstead of hunting through six tutorials and reconciling them by hand each time if Eleventy defaults changes or patterns shift, you get the new version of Baseline on `npm install`.\n\n---\n\n## What the Baseline modules do\n\nFive modules, each wiring a distinct concern into Eleventy:\n\n{% stepsBlock "compact" %}\n\n- **[[assets]]**: the asset pipeline. One CSS entry point per directory through PostCSS, one JS entry point through esbuild, and inline filters (`inlinePostCSS`, `inlineESbuild`) for critical-path CSS or JS.\n- **[[head]]**: a `<baseline-head>` placeholder that gets replaced with a sorted, deduped element list. Charset, viewport, title, description, robots, canonical, hreflang, plus the SEO payload (Open Graph, Twitter, JSON-LD). You drop the placeholder in your layout once.\n- **[[multilang]]**: directory-based multilingual support. Per-language collections, hreflang, a translation map, and the standard i18n filters (it wraps Eleventy\'s `I18nPlugin`). Opt-in.\n- **[[navigator]]**: runtime-introspection surface and public read surface. A `phpinfo()`-style virtual page that dumps current build state (on in development by default), the globals and filters used to build it, and the `_navigator` global (`{ nodes, edges, backlinks }`) for cross-page reads of the content graph.\n- **[[sitemap]]**: an XML sitemap. Every page is included unless you exclude it. When `multilang` is active, you get per-language sitemaps plus an index.\n\n{% endstepsBlock %}\n\nThreading the modules together is **page context** at `_pageContext`: a normalised per-page object the head, multilang, and sitemap modules all read from internally. Your templates can read it too. See the [[page-context | page context reference]].\n\n---\n\n## Baseline content helpers\n\nAlongside the modules, Baseline registers a small set of additions the moment you load it. These are always on because they are too small to be worth opting in or out of:\n\n{% stepsBlock "compact" %}\n\n- **Filters**: `markdownify`, `relatedPosts`, `isString`. See the [[filters | filters reference]].\n- **Globals**: a date-formatting helper, plus the `_baseline` data tree (`env`, `features`, `paths`) that templates can read at any time. See the [[globals | globals reference]].\n- **An [[image-shortcode | image shortcode]]** built on top of [eleventy-img](https://www.11ty.dev/docs/plugins/image/): AVIF and WebP, responsive widths, lazy loading. Alt text is required; the build warns if you skip it.\n\n{% endstepsBlock %}\n\nAnd three behaviours that need no configuration at all:\n\n{% stepsBlock "compact" %}\n\n- A **drafts preprocessor**: any template with `draft: true` in front matter is excluded from production builds.\n- A **dev image pipeline**: `eleventy-img` is wired up for in-flight transforms during `--serve`.\n- **Passthrough copy** for the `static/` directory: anything in there is copied to the site root as-is.\n\n{% endstepsBlock %}\n\nThe full surface lives in the [[core-reference | core reference]] chapter.\n\n---\n\n## Stability and scope\n\nBaseline is in active development. Versions ship as `0.1.0-next.X` and that is a deliberate signal: things may shift between releases, and you should pin a version when you build something serious on top.\n\nThe five modules above are the supported surface today. The head module also emits a full SEO payload: canonical, Open Graph, Twitter cards, and a JSON-LD graph, configured through `settings.seo` and per-page front matter.\n\nIf something in the docs claims a behaviour you cannot reproduce, the docs are probably wrong. Please [open an issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\n---\n\n## Where to go next\n\n- The [[concept | concept]] chapter for the mental model and community-seeded conventions.\n- The [[quickstart | quickstart]] for a checklist that gets you a running site.\n- The [[simple-baseline-site | simple-site]] tutorial for a guided walk through the same checklist with reasoning.\n- The [[architecture-snapshot | architecture snapshot]] for a deeper look at the three layers if you want it.\n\nAlready have an Eleventy site you want to graft Baseline onto? See [[integrate-eleventy-base-blog]].\n',
             url: '/docs/introduction/overview/',
             outputPath: './dist/docs/introduction/overview/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-06-02T10:23:27.000Z },
          inputPath: './src/content/docs/00.introduction/01.overview.md',
          fileSlug: '01.overview',
          filePathStem: '/content/docs/00.introduction/01.overview',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/introduction/overview/index.html',
          url: '/docs/introduction/overview/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/00.introduction/03.quickstart.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '03.quickstart',
             filePathStem: '/content/docs/00.introduction/03.quickstart',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThe minimum working setup. A checklist; for a guided walk with reasoning, see the [[simple-baseline-site | simple-site tutorial]].\n\n---\n\n## Prerequisites\n\n{% stepsBlock %}\n\n- Node 20.15.0 or newer, and npm.\n- A `package.json` with `"type": "module"` and Eleventy scripts:\n  ```json\n  {\n  \t"name": "baseline-quickstart",\n  \t"type": "module",\n  \t"scripts": {\n  \t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n  \t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n  \t}\n  }\n  ```\n- A `.env` for environment-specific values:\n  ```text\n  ELEVENTY_ENV="development"\n  URL="http://localhost:8080/"\n  ```\n  Baseline reads `ELEVENTY_ENV` to decide what to enable in development versus production. `URL` becomes the canonical site URL when set. The other entries you might add are project-specific.\n\n{% endstepsBlock %}\n\n---\n\n## 1) Install\n\n```bash\nmkdir baseline-quickstart\ncd baseline-quickstart\nnpm init -y\nnpm install @11ty/eleventy @apleasantview/eleventy-plugin-baseline @11ty/eleventy-img\n```\n\n---\n\n## 2) Configure\n\nCreate `eleventy.config.js` at the project root:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\n\nconst settings = {\n\ttitle: \'My Site\',\n\turl: process.env.URL,\n\tdefaultLanguage: \'en\'\n};\n\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\tsitemap: true,\n\t\t\tnavigator: true\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\nTwo things to notice:\n\n{% stepsBlock %}\n\n- `baseline()` takes two arguments. `settings` is the site identity (title, url, languages, head extras); `options` is runtime behaviour (which modules are on, log verbosity, per-module options).\n- The `config` re-export looks unusual. It is. That way both Baseline and Eleventy agree on where things live (`src/` as input, `dist/` as output, the asset and public folders).\n\n{% endstepsBlock %}\n\n{% alertBlock "info" %}\n\n### Why Baseline re-exports `config`.\n\nEleventy reads its directory configuration before any plugin runs, so a plugin cannot set those for you from inside `addPlugin()`. The [[config-export | config-export reference]] has the full version.\n\n{% endalertBlock %}\n\n---\n\n## 3) Project files\n\nCreate the rest of the project files:\n\n{% stepsBlock %}\n\n- `src/_data/settings.js`: site identity (`title`, `url`, `defaultLanguage`, `languages`, `head` extras).\n- `src/_includes/layouts/base.njk`: base layout. Drop `<baseline-head></baseline-head>` in place of the `<head>` element. That **placeholder** is the one element you write yourself.\n- `src/content/pages/index.md`: a starter page with front matter and a body.\n- `src/assets/assets.11tydata.js`, `src/assets/css/index.css`, `src/assets/js/index.js`: asset entry points (one CSS, one JS).\n- `src/static/`: passthrough-copied to the site root. The on-disk folder is `static/`; the virtual directory key Baseline registers is `public`.\n\n{% endstepsBlock %}\n\n---\n\n## 4) Run and build\n\n{% stepsBlock %}\n\n- Development:\n  ```bash\n  npm start\n  ```\n  Open http://localhost:8080/. Check `dist/` for output, including `dist/sitemap.xml`.\n- Production build:  \n  Change `URL` in `.env` to an absolute URL. On a deployed site that\'s your real production URL; for this exercise, any absolute URL (e.g. `https://www.example.com/`) works to verify the output. Then run:\n  ```bash\n  npm run build\n  ```\n  Inspect `dist/` for the final files. Remember to reset `URL` in `.env` to "http://localhost:8080/".\n\n{% endstepsBlock %}\n\nThe **drafts preprocessor** (a build-time filter that drops templates marked `draft: true`) is on automatically: drafts are excluded from production builds (`npm run build`) and included in development (`npm start`).\n\n---\n\n## Next steps\n\n- The [[concept | concept chapter]] chapter for the mental model and community-seeded conventions.\n- The [[simple-baseline-site | simple site]] tutorial for a fuller walk-through.\n- For multilingual: see the [[multilingual-baseline-site | multilingual site]] tutorial.\n- The [[head-and-noindex | head and noindex]] tutorial once you have the basics working.\n- The [[architecture-snapshot | architecture snapshot]] for the deeper read on how the plugin is built.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Introduction',
             title: 'Quickstart',
             description: 'The minimum working setup: install, configure, run.',
             slug: 'quickstart',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/00.introduction/03.quickstart.md',
             fileSlug: '03.quickstart',
             filePathStem: '/content/docs/00.introduction/03.quickstart',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              '\nThe minimum working setup. A checklist; for a guided walk with reasoning, see the [[simple-baseline-site | simple-site tutorial]].\n\n---\n\n## Prerequisites\n\n{% stepsBlock %}\n\n- Node 20.15.0 or newer, and npm.\n- A `package.json` with `"type": "module"` and Eleventy scripts:\n  ```json\n  {\n  \t"name": "baseline-quickstart",\n  \t"type": "module",\n  \t"scripts": {\n  \t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n  \t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n  \t}\n  }\n  ```\n- A `.env` for environment-specific values:\n  ```text\n  ELEVENTY_ENV="development"\n  URL="http://localhost:8080/"\n  ```\n  Baseline reads `ELEVENTY_ENV` to decide what to enable in development versus production. `URL` becomes the canonical site URL when set. The other entries you might add are project-specific.\n\n{% endstepsBlock %}\n\n---\n\n## 1) Install\n\n```bash\nmkdir baseline-quickstart\ncd baseline-quickstart\nnpm init -y\nnpm install @11ty/eleventy @apleasantview/eleventy-plugin-baseline @11ty/eleventy-img\n```\n\n---\n\n## 2) Configure\n\nCreate `eleventy.config.js` at the project root:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\n\nconst settings = {\n\ttitle: \'My Site\',\n\turl: process.env.URL,\n\tdefaultLanguage: \'en\'\n};\n\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\tsitemap: true,\n\t\t\tnavigator: true\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\nTwo things to notice:\n\n{% stepsBlock %}\n\n- `baseline()` takes two arguments. `settings` is the site identity (title, url, languages, head extras); `options` is runtime behaviour (which modules are on, log verbosity, per-module options).\n- The `config` re-export looks unusual. It is. That way both Baseline and Eleventy agree on where things live (`src/` as input, `dist/` as output, the asset and public folders).\n\n{% endstepsBlock %}\n\n{% alertBlock "info" %}\n\n### Why Baseline re-exports `config`.\n\nEleventy reads its directory configuration before any plugin runs, so a plugin cannot set those for you from inside `addPlugin()`. The [[config-export | config-export reference]] has the full version.\n\n{% endalertBlock %}\n\n---\n\n## 3) Project files\n\nCreate the rest of the project files:\n\n{% stepsBlock %}\n\n- `src/_data/settings.js`: site identity (`title`, `url`, `defaultLanguage`, `languages`, `head` extras).\n- `src/_includes/layouts/base.njk`: base layout. Drop `<baseline-head></baseline-head>` in place of the `<head>` element. That **placeholder** is the one element you write yourself.\n- `src/content/pages/index.md`: a starter page with front matter and a body.\n- `src/assets/assets.11tydata.js`, `src/assets/css/index.css`, `src/assets/js/index.js`: asset entry points (one CSS, one JS).\n- `src/static/`: passthrough-copied to the site root. The on-disk folder is `static/`; the virtual directory key Baseline registers is `public`.\n\n{% endstepsBlock %}\n\n---\n\n## 4) Run and build\n\n{% stepsBlock %}\n\n- Development:\n  ```bash\n  npm start\n  ```\n  Open http://localhost:8080/. Check `dist/` for output, including `dist/sitemap.xml`.\n- Production build:  \n  Change `URL` in `.env` to an absolute URL. On a deployed site that\'s your real production URL; for this exercise, any absolute URL (e.g. `https://www.example.com/`) works to verify the output. Then run:\n  ```bash\n  npm run build\n  ```\n  Inspect `dist/` for the final files. Remember to reset `URL` in `.env` to "http://localhost:8080/".\n\n{% endstepsBlock %}\n\nThe **drafts preprocessor** (a build-time filter that drops templates marked `draft: true`) is on automatically: drafts are excluded from production builds (`npm run build`) and included in development (`npm start`).\n\n---\n\n## Next steps\n\n- The [[concept | concept chapter]] chapter for the mental model and community-seeded conventions.\n- The [[simple-baseline-site | simple site]] tutorial for a fuller walk-through.\n- For multilingual: see the [[multilingual-baseline-site | multilingual site]] tutorial.\n- The [[head-and-noindex | head and noindex]] tutorial once you have the basics working.\n- The [[architecture-snapshot | architecture snapshot]] for the deeper read on how the plugin is built.\n',
             url: '/docs/introduction/quickstart/',
             outputPath: './dist/docs/introduction/quickstart/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-05-18T00:40:30.000Z },
          inputPath: './src/content/docs/00.introduction/03.quickstart.md',
          fileSlug: '03.quickstart',
          filePathStem: '/content/docs/00.introduction/03.quickstart',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/introduction/quickstart/index.html',
          url: '/docs/introduction/quickstart/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/01.concept/00.index.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '00.index',
             filePathStem: '/content/docs/01.concept/00.index',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           `\nThe [[concept-overview | concept overview]] is the mental model behind the plugin. [[project-structure | Project structure]] are the small set of rules that keep Baseline out of your way, and [[content-organisation | content organisation]] is the page-data pattern those rules assume.\n\nBaseline also provides a small set of [[content-helpers | content helpers]] and finally, the [[architecture-snapshot | architecture snapshot]] gives you the low-down about the plugin's internal system.\n\n---\n\n## In this chapter\n\n{% include "partials/chapter-toc.njk" %}\n`,
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: '/docs/concept/',
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Concept',
             title: 'Concept',
             description:
              'Explains the foundational concept behind the plugin and how its structure, content organization, and architecture work together.',
             slug: 'concept',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/01.concept/00.index.md',
             fileSlug: '00.index',
             filePathStem: '/content/docs/01.concept/00.index',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              `\nThe [[concept-overview | concept overview]] is the mental model behind the plugin. [[project-structure | Project structure]] are the small set of rules that keep Baseline out of your way, and [[content-organisation | content organisation]] is the page-data pattern those rules assume.\n\nBaseline also provides a small set of [[content-helpers | content helpers]] and finally, the [[architecture-snapshot | architecture snapshot]] gives you the low-down about the plugin's internal system.\n\n---\n\n## In this chapter\n\n{% include "partials/chapter-toc.njk" %}\n`,
             url: '/docs/concept/',
             outputPath: './dist/docs/concept/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-06-04T00:42:58.000Z },
          inputPath: './src/content/docs/01.concept/00.index.md',
          fileSlug: '00.index',
          filePathStem: '/content/docs/01.concept/00.index',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/concept/index.html',
          url: '/docs/concept/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/01.concept/01.overview.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '01.overview',
             filePathStem: '/content/docs/01.concept/01.overview',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nBaseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.\n\n---\n\n## The one-sentence model\n\nBaseline makes the setup decisions (directory structure, template engine, image formats, meta tags, asset bundling, sitemap) so you can skip the wiring and start building.\n\n---\n\n## What Baseline handles, what you handle\n\n**Baseline handles**\n\n- Directory structure: `src/` as input, `dist/` as output, with a standard layout for assets, data, and templates.\n- The asset pipeline: PostCSS for CSS, esbuild for JS. One entry point per directory.\n- Image handling: an `image` shortcode wired on top of `eleventy-img` (AVIF and WebP, responsive widths, lazy loading).\n- The `<head>` tags: charset, viewport, title, description, robots, canonical, hreflang. You drop a `<baseline-head>` placeholder in your layout and the plugin fills it.\n- Sitemaps: XML generation, with per-language sitemaps plus an index when multilang is on.\n- Debug tooling: globals and filters for inspecting template data, plus an optional virtual page in development.\n\n**You handle**\n\n- Visual design, CSS, layout.\n- Content structure and naming.\n- Templates and layout logic.\n- Deployment.\n\nWhat that looks like on disk is the annotated tree at the end of this page.\n\n---\n\n## Two configuration surfaces\n\nBaseline\'s configuration has two parts, and they do different jobs.\n\n<br>\n\n**1. The plugin call.** `baseline(settings, options)` takes two arguments:\n\n{% stepsBlock "compact" %}\n\n- `settings` is your **site identity**: title, tagline, url, default language, the language map, and any extra head data you want available to templates.\n- `options` is **runtime behaviour**: which optional modules are on, how verbose the build logs are, and fine-grained module options like `head.titleSeparator` or `assets.esbuild`.\n\n{% endstepsBlock %}\n\n```js\nimport baseline from \'@apleasantview/eleventy-plugin-baseline\';\n\nconst settings = {\n\ttitle: \'My Site\',\n\turl: \'https://www.example.com/\',\n\tdefaultLanguage: \'en\'\n};\n\nawait eleventyConfig.addPlugin(\n\tbaseline(settings, {\n\t\tmultilingual: false,\n\t\tsitemap: true,\n\t\tnavigator: true\n\t})\n);\n```\n\nThe full option list is on the [[plugin-entrypoint | plugin entry point reference]]; the settings shape is on the [[site-settings | site settings reference]].\n\n<br>\n\n**2. The re-exported `config`.** Baseline ships an Eleventy directory configuration alongside the plugin and asks you to re-export it from your `eleventy.config.js`:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\n\nexport const config = baselineConfig;\n```\n\nEleventy reads the directory configuration before any plugin runs, so the plugin cannot set it for you from inside `addPlugin()`. Re-exporting `config` is how both pieces agree on where things live (`src/` as input, `dist/` as output, `assets` and `public` as virtual asset directories). The full explanation is on the [[config-export | configuration export reference]].\n\nThe plugin call controls what Baseline does. The config export controls where Eleventy looks. They stay separate because Eleventy needs the directory shape before plugins exist.\n\n---\n\n## The `<head>` placeholder\n\nMost of what Baseline does is invisible: it runs during the build, writes to `dist/`, and you never see the wiring. There is one visible piece you place by hand, the **placeholder**.\n\nYou drop `<baseline-head>` in place of the `<head>` element in a base layout:\n\n```html\n<html lang="en">\n\t<baseline-head></baseline-head>\n\t<body>\n\t\t...\n\t</body>\n</html>\n```\n\nAt **transform-time** (the moment a rendered template is about to be written to disk), the head module replaces the placeholder with a full `<head>` element containing the resolved tags for the current page.\n\nThat is the seam between Baseline\'s automation and your own templates: everything else is configuration; the placeholder is the one thing you place yourself.\n\nSee the [[head | head module page]] for the full pipeline.\n\n---\n\n## Where to go next\n\n- The [[project-structure | project structure]] for the minimum working configuration.\n- The [[content-organisation | content organisation]] strategy.\n- The [[architecture-snapshot | architecture snapshot]] for the deeper model behind the plugin: state, runtime, modules.\n- The [[simple-baseline-site | simple-site tutorial]] for a guided walk through the same configuration with reasoning.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Concept',
             title: 'Concept overview',
             description:
              'A conceptual map of Baseline: what it handles, the placeholder, and the two configuration surfaces.',
             slug: 'concept-overview',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/01.concept/01.overview.md',
             fileSlug: '01.overview',
             filePathStem: '/content/docs/01.concept/01.overview',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              '\nBaseline makes the structural decisions Eleventy leaves open and wires them into a small set of feature modules that work together. This page is the mental model: what Baseline handles, what stays yours, and how you configure it.\n\n---\n\n## The one-sentence model\n\nBaseline makes the setup decisions (directory structure, template engine, image formats, meta tags, asset bundling, sitemap) so you can skip the wiring and start building.\n\n---\n\n## What Baseline handles, what you handle\n\n**Baseline handles**\n\n- Directory structure: `src/` as input, `dist/` as output, with a standard layout for assets, data, and templates.\n- The asset pipeline: PostCSS for CSS, esbuild for JS. One entry point per directory.\n- Image handling: an `image` shortcode wired on top of `eleventy-img` (AVIF and WebP, responsive widths, lazy loading).\n- The `<head>` tags: charset, viewport, title, description, robots, canonical, hreflang. You drop a `<baseline-head>` placeholder in your layout and the plugin fills it.\n- Sitemaps: XML generation, with per-language sitemaps plus an index when multilang is on.\n- Debug tooling: globals and filters for inspecting template data, plus an optional virtual page in development.\n\n**You handle**\n\n- Visual design, CSS, layout.\n- Content structure and naming.\n- Templates and layout logic.\n- Deployment.\n\nWhat that looks like on disk is the annotated tree at the end of this page.\n\n---\n\n## Two configuration surfaces\n\nBaseline\'s configuration has two parts, and they do different jobs.\n\n<br>\n\n**1. The plugin call.** `baseline(settings, options)` takes two arguments:\n\n{% stepsBlock "compact" %}\n\n- `settings` is your **site identity**: title, tagline, url, default language, the language map, and any extra head data you want available to templates.\n- `options` is **runtime behaviour**: which optional modules are on, how verbose the build logs are, and fine-grained module options like `head.titleSeparator` or `assets.esbuild`.\n\n{% endstepsBlock %}\n\n```js\nimport baseline from \'@apleasantview/eleventy-plugin-baseline\';\n\nconst settings = {\n\ttitle: \'My Site\',\n\turl: \'https://www.example.com/\',\n\tdefaultLanguage: \'en\'\n};\n\nawait eleventyConfig.addPlugin(\n\tbaseline(settings, {\n\t\tmultilingual: false,\n\t\tsitemap: true,\n\t\tnavigator: true\n\t})\n);\n```\n\nThe full option list is on the [[plugin-entrypoint | plugin entry point reference]]; the settings shape is on the [[site-settings | site settings reference]].\n\n<br>\n\n**2. The re-exported `config`.** Baseline ships an Eleventy directory configuration alongside the plugin and asks you to re-export it from your `eleventy.config.js`:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\n\nexport const config = baselineConfig;\n```\n\nEleventy reads the directory configuration before any plugin runs, so the plugin cannot set it for you from inside `addPlugin()`. Re-exporting `config` is how both pieces agree on where things live (`src/` as input, `dist/` as output, `assets` and `public` as virtual asset directories). The full explanation is on the [[config-export | configuration export reference]].\n\nThe plugin call controls what Baseline does. The config export controls where Eleventy looks. They stay separate because Eleventy needs the directory shape before plugins exist.\n\n---\n\n## The `<head>` placeholder\n\nMost of what Baseline does is invisible: it runs during the build, writes to `dist/`, and you never see the wiring. There is one visible piece you place by hand, the **placeholder**.\n\nYou drop `<baseline-head>` in place of the `<head>` element in a base layout:\n\n```html\n<html lang="en">\n\t<baseline-head></baseline-head>\n\t<body>\n\t\t...\n\t</body>\n</html>\n```\n\nAt **transform-time** (the moment a rendered template is about to be written to disk), the head module replaces the placeholder with a full `<head>` element containing the resolved tags for the current page.\n\nThat is the seam between Baseline\'s automation and your own templates: everything else is configuration; the placeholder is the one thing you place yourself.\n\nSee the [[head | head module page]] for the full pipeline.\n\n---\n\n## Where to go next\n\n- The [[project-structure | project structure]] for the minimum working configuration.\n- The [[content-organisation | content organisation]] strategy.\n- The [[architecture-snapshot | architecture snapshot]] for the deeper model behind the plugin: state, runtime, modules.\n- The [[simple-baseline-site | simple-site tutorial]] for a guided walk through the same configuration with reasoning.\n',
             url: '/docs/concept/concept-overview/',
             outputPath: './dist/docs/concept/concept-overview/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-05-17T23:22:25.000Z },
          inputPath: './src/content/docs/01.concept/01.overview.md',
          fileSlug: '01.overview',
          filePathStem: '/content/docs/01.concept/01.overview',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/concept/concept-overview/index.html',
          url: '/docs/concept/concept-overview/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/01.concept/02.project-structure.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '02.project-structure',
             filePathStem: '/content/docs/01.concept/02.project-structure',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThe folder structure that keeps Baseline out of your way. If you\'ve read the [[overview | overview]] and the [[concept-overview | concept overview]], you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own.\n\n---\n\n## The shape of a Baseline project\n\nBaseline expects a small, predictable layout. You can change it but the cost is real.\n\n```\nyour-site/\n  eleventy.config.js     # plugin call + config re-export\n  package.json           # "type": "module" – Baseline is ESM\n  .env                   # ELEVENTY_ENV, URL\n  src/\n    _data/\n      settings.js        # site identity (read by head, sitemap, multilang)\n    _includes/\n      layouts/\n        base.njk         # contains <baseline-head>\n    assets/\n      css/index.css      # the one CSS entry point; @import the rest\n      js/index.js        # the one JS entry point; import the rest\n    content/             # your pages\n    static/              # passthrough-copied to the site root\n  dist/                  # build output\n```\n\nThree things are non-negotiable, or close to it:\n\n- ESM. `package.json` carries `"type": "module"`.\n- Node 20.15.0 or newer. Older versions work for a while, then suddenly don\'t.\n- `src/` for input, `dist/` for output. Baseline ships a directory configuration that says so.\n\nEverything else has a default. The closer you stay, the less you have to think about.\n\n---\n\n## The plugin call\n\nThe plugin call has a specific shape. Use this form, even on small projects.\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\tsitemap: true,\n\t\t\tnavigator: true\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\nTwo arguments: site identity, then runtime behaviour. The `config` re-export at the bottom is the unusual part. Eleventy reads its directory configuration before any plugin runs, so Baseline ships that block as a separate export and asks you to forward it.\n\nSkip the re-export and the virtual directories Baseline registers (`assets`, `public`) won\'t be there, and a few modules will get quietly confused. The [[config-export | config-export reference]] has the full version.\n\n## Settings (`src/_data/settings.js`)\n\nSettings is site identity. The head module reads it, so do canonical resolution, sitemap URLs, and the multilingual machinery. By convention it lives at `src/_data/settings.js` so the same object is also available in templates as `settings`.\n\n```js\nexport default {\n\ttitle: \'\', // <title> composition, og:site_name, navigator\n\ttagline: \'\', // home page suffix, default meta description\n\turl: process.env.URL, // absolute, with protocol; anchors canonical and sitemap URLs\n\tnoindex: false, // site-wide robots: noindex switch\n\tdefaultLanguage: \'en\', // BCP47 code; required for multilingual mode\n\tlanguages: {}, // map of lang to {}; required for multilingual mode\n\thead: {\n\t\t// Site-wide head extras. Each entry\'s keys become attributes on\n\t\t// the rendered tag. Page-level extras belong in front matter.\n\t\tlink: [{ rel: \'stylesheet\', href: \'/assets/css/index.css\' }],\n\t\tscript: [{ src: \'/assets/js/index.js\', defer: true }],\n\t\tmeta: [],\n\t\tstyle: []\n\t}\n};\n```\n\nA few things worth knowing upfront:\n\n- `url` should be absolute, with protocol. Baseline warns once at startup if it is missing: canonicals are then omitted, and other absolute URLs (sitemap, social images) fall back to relative.\n- Head extras live in `settings.head`. There is no `_data/head.js` to maintain.\n- Every key is optional. Wrong types are logged but don\'t throw.\n\nSettings is identity. Module behaviour goes in options. The full shape is in the [[site-settings | site-settings reference]].\n\n---\n\n## Options (defaults you usually keep)\n\nThe shipped defaults are deliberate. Most projects don\'t change them.\n\n{% tableBlock true %}\n\n| Option                | Default  | What it does                                                                                                                                         |\n| --------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `verbose`             | `true`   | Build narrative: banner, version line, `info`-level logs. Warnings and errors emit either way. Set to `false` for a silent build.                    |\n| `multilingual`        | `false`  | Activates the `multilang` module (with the prerequisites below).                                                                                     |\n| `sitemap`             | `true`   | Generates `/sitemap.xml`, or per-language sitemaps in multilingual mode.                                                                             |\n| `navigator`           | dev only | Gates the runtime-introspection virtual page (`/navigator-core.html`). The `_navigator` read surface and debug filters/globals are always available. |\n| `assets.esbuild`      | `{}`     | Forwarded to esbuild on every entry-point build.                                                                                                     |\n| `head.titleSeparator` | `\' – \'`  | Sits between page title and site title in `<title>`.                                                                                                 |\n| `head.showGenerator`  | `false`  | Adds `<meta name="generator">` if you want Baseline credited.                                                                                        |\n\n{% endtableBlock %}\n\nThe `assets` and `head` modules are always on. You can tune them; you cannot switch them off. The user-facing key is `multilingual` even though the module is named `multilang`. That is on purpose.\n\n---\n\n### Eleventy environment variables and scripts\n\nTwo environment variables steer build behaviour. One is set for you; one is yours to set.\n\n{% tableBlock true %}\n\n| Variable            | Who sets it | What it flips                                                     |\n| ------------------- | ----------- | ----------------------------------------------------------------- |\n| `ELEVENTY_RUN_MODE` | Eleventy    | Drafts (dropped on `build`), image shortcode `transformOnRequest` |\n| `ELEVENTY_ENV`      | You         | Navigator template, PostCSS minification                          |\n\n{% endtableBlock %}\n\n`ELEVENTY_RUN_MODE` is filled in automatically: `eleventy --serve` makes it `serve`; `eleventy` makes it `build`. Don\'t override it. If you find yourself wanting to, that is a signal something else is wrong.\n\n`ELEVENTY_ENV` is yours. Set it in `.env` for development, and on the production command via `cross-env`. The shape and `.env` most projects land on:\n\n```json\n{\n\t"scripts": {\n\t\t"dev": "rimraf dist/ && npx @11ty/eleventy --serve",\n\t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n\t}\n}\n```\n\n```text\n# .env\nELEVENTY_ENV=development\nURL=http://localhost:8080/\n```\n\nDon\'t reach for custom environment variables for things these two already cover. If you find yourself reading `process.env.SOMETHING_CUSTOM` to decide whether to render a page, check first whether one of the two above is the real signal.\n\n---\n\n### Multilingual activation\n\nThe `multilang` module activates only when all three of these are present:\n\n- `multilingual: true` in options\n- `defaultLanguage` set to a real BCP47 code in settings\n- `languages` is a non-empty map in settings\n\nMiss one and the module quietly bails with an info log. Half-configured multilingual is worse than single-language; the silence is on purpose. The [[multilingual-baseline-site | multilingual tutorial]] walks through the full setup.\n\n---\n\n## Static files\n\nTwo names for the same place, on purpose.\n\n- On disk: `src/static/`.\n- In templates and config: `public`. Available as `_baseline.paths.public`.\n\nThe folder name follows the convention you already have. The virtual key matches what most static-site generators call this directory. Drop favicons, `robots.txt`, downloadable assets, anything else that should land at a known URL without processing.\n\n---\n\n## Assets\n\nTwo entry points. That\'s it.\n\n```\nsrc/assets/css/index.css\nsrc/assets/js/index.js\n```\n\nReach the rest through `@import` and `import` from there. Subfolders with their own `index.js` or `index.css` are picked up as separate bundles too, which is handy when one page wants its own JS. Anything not named `index` is skipped silently by the compile guard. This is intentional, not an oversight.\n\nCompiled output lands under `dist/assets/`, mirroring the input layout. So `src/assets/css/index.css` becomes `/assets/css/index.css` at the served URL.\n\n{% alertBlock "warning" %}\n\n**Loading them is on you.**\n\nBaseline compiles, but it does not inject `<link>` or `<script>` tags for the bundles. Reference each one in `settings.head.link` or `settings.head.script` (see the example above) and the head module will emit the tag on every page. Skip this and the bundles compile but never load.\n\n{% endalertBlock %}\n\n---\n\n### Tuning the processors\n\nesbuild defaults to `minify: true, target: \'es2020\'`. Override through `options.assets.esbuild`; values are merged on top of the defaults.\n\n```js\nbaseline(settings, {\n\tassets: {\n\t\tesbuild: {\n\t\t\tminify: process.env.ELEVENTY_ENV === \'production\',\n\t\t\ttarget: \'es2017\'\n\t\t}\n\t}\n});\n```\n\nPostCSS has no plugin-level options. Configure it through your own config file: `postcss-load-config` picks up `postcss.config.{js,cjs,mjs}`, `.postcssrc`, or a `postcss` block in `package.json`. Without one, the bundled fallback runs (`postcss-import`, `postcss-preset-env`, and `cssnano` in production).\n\nThe resolved PostCSS config is cached for the lifetime of the process. Restart Eleventy to pick up changes to `postcss.config.js`. The [[customise-a'... 2121 more characters,
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Concept',
             title: 'Project structure',
             description:
              'How to stay in step with Baseline so the plugin stays out of your way: project shape, the plugin call, settings, options, environment variables, and the small set of seams Baseline expects to own.',
             slug: 'project-structure',
             date: 2026-05-02T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/01.concept/02.project-structure.md',
             fileSlug: '02.project-structure',
             filePathStem: '/content/docs/01.concept/02.project-structure',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-02T00:00:00.000Z,
             rawInput:
              '\nThe folder structure that keeps Baseline out of your way. If you\'ve read the [[overview | overview]] and the [[concept-overview | concept overview]], you already have the shape. This page is the practical companion: where files go, how the call looks, which environment variables matter, and the few seams Baseline expects to own.\n\n---\n\n## The shape of a Baseline project\n\nBaseline expects a small, predictable layout. You can change it but the cost is real.\n\n```\nyour-site/\n  eleventy.config.js     # plugin call + config re-export\n  package.json           # "type": "module" – Baseline is ESM\n  .env                   # ELEVENTY_ENV, URL\n  src/\n    _data/\n      settings.js        # site identity (read by head, sitemap, multilang)\n    _includes/\n      layouts/\n        base.njk         # contains <baseline-head>\n    assets/\n      css/index.css      # the one CSS entry point; @import the rest\n      js/index.js        # the one JS entry point; import the rest\n    content/             # your pages\n    static/              # passthrough-copied to the site root\n  dist/                  # build output\n```\n\nThree things are non-negotiable, or close to it:\n\n- ESM. `package.json` carries `"type": "module"`.\n- Node 20.15.0 or newer. Older versions work for a while, then suddenly don\'t.\n- `src/` for input, `dist/` for output. Baseline ships a directory configuration that says so.\n\nEverything else has a default. The closer you stay, the less you have to think about.\n\n---\n\n## The plugin call\n\nThe plugin call has a specific shape. Use this form, even on small projects.\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\tsitemap: true,\n\t\t\tnavigator: true\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\nTwo arguments: site identity, then runtime behaviour. The `config` re-export at the bottom is the unusual part. Eleventy reads its directory configuration before any plugin runs, so Baseline ships that block as a separate export and asks you to forward it.\n\nSkip the re-export and the virtual directories Baseline registers (`assets`, `public`) won\'t be there, and a few modules will get quietly confused. The [[config-export | config-export reference]] has the full version.\n\n## Settings (`src/_data/settings.js`)\n\nSettings is site identity. The head module reads it, so do canonical resolution, sitemap URLs, and the multilingual machinery. By convention it lives at `src/_data/settings.js` so the same object is also available in templates as `settings`.\n\n```js\nexport default {\n\ttitle: \'\', // <title> composition, og:site_name, navigator\n\ttagline: \'\', // home page suffix, default meta description\n\turl: process.env.URL, // absolute, with protocol; anchors canonical and sitemap URLs\n\tnoindex: false, // site-wide robots: noindex switch\n\tdefaultLanguage: \'en\', // BCP47 code; required for multilingual mode\n\tlanguages: {}, // map of lang to {}; required for multilingual mode\n\thead: {\n\t\t// Site-wide head extras. Each entry\'s keys become attributes on\n\t\t// the rendered tag. Page-level extras belong in front matter.\n\t\tlink: [{ rel: \'stylesheet\', href: \'/assets/css/index.css\' }],\n\t\tscript: [{ src: \'/assets/js/index.js\', defer: true }],\n\t\tmeta: [],\n\t\tstyle: []\n\t}\n};\n```\n\nA few things worth knowing upfront:\n\n- `url` should be absolute, with protocol. Baseline warns once at startup if it is missing: canonicals are then omitted, and other absolute URLs (sitemap, social images) fall back to relative.\n- Head extras live in `settings.head`. There is no `_data/head.js` to maintain.\n- Every key is optional. Wrong types are logged but don\'t throw.\n\nSettings is identity. Module behaviour goes in options. The full shape is in the [[site-settings | site-settings reference]].\n\n---\n\n## Options (defaults you usually keep)\n\nThe shipped defaults are deliberate. Most projects don\'t change them.\n\n{% tableBlock true %}\n\n| Option                | Default  | What it does                                                                                                                                         |\n| --------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `verbose`             | `true`   | Build narrative: banner, version line, `info`-level logs. Warnings and errors emit either way. Set to `false` for a silent build.                    |\n| `multilingual`        | `false`  | Activates the `multilang` module (with the prerequisites below).                                                                                     |\n| `sitemap`             | `true`   | Generates `/sitemap.xml`, or per-language sitemaps in multilingual mode.                                                                             |\n| `navigator`           | dev only | Gates the runtime-introspection virtual page (`/navigator-core.html`). The `_navigator` read surface and debug filters/globals are always available. |\n| `assets.esbuild`      | `{}`     | Forwarded to esbuild on every entry-point build.                                                                                                     |\n| `head.titleSeparator` | `\' – \'`  | Sits between page title and site title in `<title>`.                                                                                                 |\n| `head.showGenerator`  | `false`  | Adds `<meta name="generator">` if you want Baseline credited.                                                                                        |\n\n{% endtableBlock %}\n\nThe `assets` and `head` modules are always on. You can tune them; you cannot switch them off. The user-facing key is `multilingual` even though the module is named `multilang`. That is on purpose.\n\n---\n\n### Eleventy environment variables and scripts\n\nTwo environment variables steer build behaviour. One is set for you; one is yours to set.\n\n{% tableBlock true %}\n\n| Variable            | Who sets it | What it flips                                                     |\n| ------------------- | ----------- | ----------------------------------------------------------------- |\n| `ELEVENTY_RUN_MODE` | Eleventy    | Drafts (dropped on `build`), image shortcode `transformOnRequest` |\n| `ELEVENTY_ENV`      | You         | Navigator template, PostCSS minification                          |\n\n{% endtableBlock %}\n\n`ELEVENTY_RUN_MODE` is filled in automatically: `eleventy --serve` makes it `serve`; `eleventy` makes it `build`. Don\'t override it. If you find yourself wanting to, that is a signal something else is wrong.\n\n`ELEVENTY_ENV` is yours. Set it in `.env` for development, and on the production command via `cross-env`. The shape and `.env` most projects land on:\n\n```json\n{\n\t"scripts": {\n\t\t"dev": "rimraf dist/ && npx @11ty/eleventy --serve",\n\t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n\t}\n}\n```\n\n```text\n# .env\nELEVENTY_ENV=development\nURL=http://localhost:8080/\n```\n\nDon\'t reach for custom environment variables for things these two already cover. If you find yourself reading `process.env.SOMETHING_CUSTOM` to decide whether to render a page, check first whether one of the two above is the real signal.\n\n---\n\n### Multilingual activation\n\nThe `multilang` module activates only when all three of these are present:\n\n- `multilingual: true` in options\n- `defaultLanguage` set to a real BCP47 code in settings\n- `languages` is a non-empty map in settings\n\nMiss one and the module quietly bails with an info log. Half-configured multilingual is worse than single-language; the silence is on purpose. The [[multilingual-baseline-site | multilingual tutorial]] walks through the full setup.\n\n---\n\n## Static files\n\nTwo names for the same place, on purpose.\n\n- On disk: `src/static/`.\n- In templates and config: `public`. Available as `_baseline.paths.public`.\n\nThe folder name follows the convention you already have. The virtual key matches what most static-site generators call this directory. Drop favicons, `robots.txt`, downloadable assets, anything else that should land at a known URL without processing.\n\n---\n\n## Assets\n\nTwo entry points. That\'s it.\n\n```\nsrc/assets/css/index.css\nsrc/assets/js/index.js\n```\n\nReach the rest through `@import` and `import` from there. Subfolders with their own `index.js` or `index.css` are picked up as separate bundles too, which is handy when one page wants its own JS. Anything not named `index` is skipped silently by the compile guard. This is intentional, not an oversight.\n\nCompiled output lands under `dist/assets/`, mirroring the input layout. So `src/assets/css/index.css` becomes `/assets/css/index.css` at the served URL.\n\n{% alertBlock "warning" %}\n\n**Loading them is on you.**\n\nBaseline compiles, but it does not inject `<link>` or `<script>` tags for the bundles. Reference each one in `settings.head.link` or `settings.head.script` (see the example above) and the head module will emit the tag on every page. Skip this and the bundles compile but never load.\n\n{% endalertBlock %}\n\n---\n\n### Tuning the processors\n\nesbuild defaults to `minify: true, target: \'es2020\'`. Override through `options.assets.esbuild`; values are merged on top of the defaults.\n\n```js\nbaseline(settings, {\n\tassets: {\n\t\tesbuild: {\n\t\t\tminify: process.env.ELEVENTY_ENV === \'production\',\n\t\t\ttarget: \'es2017\'\n\t\t}\n\t}\n});\n```\n\nPostCSS has no plugin-level options. Configure it through your own config file: `postcss-load-config` picks up `postcss.config.{js,cjs,mjs}`, `.postcssrc`, or a `postcss` block in `package.json`. Without one, the bundled fallback runs (`postcss-import`, `postcss-preset-env`, and `cssnano` in production).\n\nThe resolved PostCSS config is cached for the lifetime of the process. Restart Eleventy to pick up changes to `postcss.config.js`. The [[customise-a'... 2121 more characters,
             url: '/docs/concept/project-structure/',
             outputPath: './dist/docs/concept/project-structure/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-05-02T00:00:00.000Z,
             dateModified: 2026-06-04T18:03:33.000Z },
          inputPath: './src/content/docs/01.concept/02.project-structure.md',
          fileSlug: '02.project-structure',
          filePathStem: '/content/docs/01.concept/02.project-structure',
          date: 2026-05-02T00:00:00.000Z,
          outputPath: './dist/docs/concept/project-structure/index.html',
          url: '/docs/concept/project-structure/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/01.concept/03.content-organisation.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '03.content-organisation',
             filePathStem: '/content/docs/01.concept/03.content-organisation',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           "\nEvery page on a Baseline site has two layers behind it.\n\nOne is structural: where the page lives, what layout wraps it, whether it shows up in nav. The other is the content's own metadata: title, description, date. They want different homes.\n\nThe pattern is to keep structure in a sibling `*.11tydata.js` file and content metadata in the page's front matter. This isn't a Baseline rule. It's a way of using Eleventy's data cascade that scales as your sections grow.\n\n```\nSTRUCTURE (*.11tydata.js)  -> section, type, layout, permalink\nCONTENT   (front matter)    -> title, slug, description, date\n```\n\nStructure is what every page in a section shares. Content is what makes one page different from the next. Mix them and the section gets harder to reason about every time you add a page.\n\n---\n\n## The structural side\n\nDrop a sibling data file next to the section's pages. Eleventy applies its values as defaults to every page in the directory, and per-page front matter can still override anything specific.\n\n`layout` is read by Eleventy. `draft` is read by Baseline's drafts preprocessor. `section` and `type` are read by Baseline into page context, so the content graph and your templates see them through the same surface.\n\n`section` is a hierarchical path written as an array, even when there's only one level. One-level is `['blog']`. Nested is `['blog', '2026']`. Nest as deep as your site needs. The shape mirrors Jekyll's `categories` – same job, same array form.\n\n```js\n// src/content/blog/blog.11tydata.js\nexport default {\n\tsection: ['blog'], // hierarchical path; nest as ['blog', '2026', 'q1']\n\ttype: 'post', // free-form classifier for collections and templates\n\n\tdraft: false, // overridden by individual pages when needed\n\tlayout: 'layouts/post.njk' // cascades to every page in the folder\n\n\t// permalink (covered below)\n};\n```\n\nKeep the ones you actually use; empty conventions rot.\n\n---\n\n## The content side\n\nFront matter stays small and per-page:\n\n```yaml\n---\ntitle: 'A short title'\nslug: 'a-short-title'\ndescription: 'One-sentence description of this specific page.'\ndate: 2026-05-01\n---\n```\n\nFour fields, every page. Title and description for the head module and link previews. Slug for the URL and for wikilinks to find the page. Date for ordering and for the sitemap's `lastmod`.\n\nPer-page exceptions go here too. If a single post needs a different layout, declare `layout` in its front matter; the cascade picks the more specific value.\n\n---\n\n## The two layers meet at the permalink\n\nThe cleanest place to see the split is the permalink function. It reads `slug` from front matter and the structural keys from the data file, and composes the URL from both.\n\nA page in `src/content/blog/` with `slug: 'first-post'` and `section: ['blog']` resolves to `/blog/first-post/`.\n\nExtend `section` to `['blog', '2026']` and every page in the folder gets `/blog/2026/<slug>/` without each post having to spell out its own path. The array is the path – nest as deep as your site needs.\n\n```js\n// src/content/blog/blog.11tydata.js\nexport default {\n\t// permalink (covered below)\n\tpermalink: function (data) {\n\t\tconst { slug, page, section } = data;\n\n\t\t// Don't try to render the data file itself as a page.\n\t\tif (page.inputPath.includes('11tydata.js')) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Front-matter slug wins; otherwise fall back to the file's own slug.\n\t\tconst slugified = slug ? this.slugify(slug) : page.fileSlug;\n\n\t\t// Compose /<section[0]>/<section[1]>/.../<slug>/.\n\t\tconst parts = (section ?? []).map((part) => this.slugify(part));\n\t\tparts.push(slugified);\n\n\t\t// Leading slash anchors to the site root; trailing slash is the project convention.\n\t\treturn '/' + parts.join('/') + '/';\n\t}\n};\n```\n\n---\n\n## Adding a language prefix\n\nFor a multilingual site, the permalink needs one more step: prefix the URL with the language code, except for the default language which sits at the site root.\n\nThe signal comes from two places already in the cascade. `data.lang` is set per language tree (typically in `en.11tydata.js`, `nl.11tydata.js`, and so on). `data.settings.defaultLanguage` lives in `_data/settings.js` and names the language that owns the root.\n\nDrop the data file one level up, at the top of your content tree, so its values cascade to every section underneath:\n\n```js\n// src/content/content.11tydata.js\nexport default {\n\tpermalink: function (data) {\n\t\t// Don't try to render the data file itself as a page.\n\t\tif (data.page.inputPath.includes('11tydata.js')) return false;\n\n\t\t// Front-matter slug wins; otherwise fall back to the file's own slug.\n\t\tconst slug = data.slug ? this.slugify(data.slug) : data.page.fileSlug;\n\n\t\t// Prefix non-default languages; default language and single-language sites sit at root.\n\t\tconst isDefaultLang = !data.lang || data.lang === data.settings?.defaultLanguage;\n\t\tconst prefix = isDefaultLang ? '' : `/${data.lang}`;\n\n\t\t// Compose /<section[0]>/<section[1]>/.../<slug>/, with optional language prefix.\n\t\tconst sections = (data.section ?? []).map((s) => this.slugify(s));\n\t\treturn `${prefix}/${[...sections, slug].join('/')}/`;\n\t}\n};\n```\n\nA page with `lang: 'en'` on a site whose `defaultLanguage` is `'en'` resolves to `/blog/first-post/`. The same page with `lang: 'nl'` resolves to `/nl/blog/first-post/`. A single-language site leaves `lang` unset and never sees a prefix.\n\nThe optional chaining on `data.settings?.defaultLanguage` keeps the check safe when `settings` or `defaultLanguage` isn't defined, which is the single-language case.\n\n---\n\n## Worth knowing\n\n- **`section` is always an array.** Even a one-level section is written as `['blog']`. The shape teaches the path-like nature of the field and lets you nest deeper without restructuring later.\n- **Front matter overrides the data file.** Eleventy resolves to the more specific value, so a single page can opt out of any default by declaring it in front matter.\n- **The data file isn't a page.** The `inputPath.includes('11tydata.js')` check returns `false` from the permalink so Eleventy doesn't try to render it.\n- **Paths use a leading slash.** Without it, the permalink resolves relative to the input subdirectory rather than the site root.\n\n---\n\n## Opting out\n\nA page can exist and render without showing up in indexes. Two keys cover the common cases – one Baseline, one Eleventy-native – and either works from front matter or the data file:\n\n```yaml\n---\nbaselineExcludeFromGraph: true        # keep this page out of the content graph\neleventyExcludeFromCollections: true  # keep this page out of all Eleventy collections\n---\n```\n\n`baselineExcludeFromGraph` is read by the content graph's prepass; the page still renders, but nothing the graph feeds (navigator listings, sitemap, related-page surfaces) will see it.\n\n`eleventyExcludeFromCollections` is Eleventy's built-in opt-out from `collections.all` and any tagged collection – reach for it when a page needs to render but shouldn't be picked up by any iteration over collections.\n\n---\n\n## See also\n\n- [[project-structure]] for the project-shape conventions this pattern slots into.\n- [[page-context|Page context]] reference for what Baseline reads off each page at cascade time.\n",
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Concept',
             title: 'Content organisation',
             slug: 'content-organisation',
             description:
              'Two layers behind every page: structural metadata (section, type, layout, permalink) lives in a sibling `*.11tydata.js`; content metadata (title, description, date) lives in front matter. A pattern, not a Baseline rule.',
             date: 2026-05-02T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/01.concept/03.content-organisation.md',
             fileSlug: '03.content-organisation',
             filePathStem: '/content/docs/01.concept/03.content-organisation',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-02T00:00:00.000Z,
             rawInput:
              "\nEvery page on a Baseline site has two layers behind it.\n\nOne is structural: where the page lives, what layout wraps it, whether it shows up in nav. The other is the content's own metadata: title, description, date. They want different homes.\n\nThe pattern is to keep structure in a sibling `*.11tydata.js` file and content metadata in the page's front matter. This isn't a Baseline rule. It's a way of using Eleventy's data cascade that scales as your sections grow.\n\n```\nSTRUCTURE (*.11tydata.js)  -> section, type, layout, permalink\nCONTENT   (front matter)    -> title, slug, description, date\n```\n\nStructure is what every page in a section shares. Content is what makes one page different from the next. Mix them and the section gets harder to reason about every time you add a page.\n\n---\n\n## The structural side\n\nDrop a sibling data file next to the section's pages. Eleventy applies its values as defaults to every page in the directory, and per-page front matter can still override anything specific.\n\n`layout` is read by Eleventy. `draft` is read by Baseline's drafts preprocessor. `section` and `type` are read by Baseline into page context, so the content graph and your templates see them through the same surface.\n\n`section` is a hierarchical path written as an array, even when there's only one level. One-level is `['blog']`. Nested is `['blog', '2026']`. Nest as deep as your site needs. The shape mirrors Jekyll's `categories` – same job, same array form.\n\n```js\n// src/content/blog/blog.11tydata.js\nexport default {\n\tsection: ['blog'], // hierarchical path; nest as ['blog', '2026', 'q1']\n\ttype: 'post', // free-form classifier for collections and templates\n\n\tdraft: false, // overridden by individual pages when needed\n\tlayout: 'layouts/post.njk' // cascades to every page in the folder\n\n\t// permalink (covered below)\n};\n```\n\nKeep the ones you actually use; empty conventions rot.\n\n---\n\n## The content side\n\nFront matter stays small and per-page:\n\n```yaml\n---\ntitle: 'A short title'\nslug: 'a-short-title'\ndescription: 'One-sentence description of this specific page.'\ndate: 2026-05-01\n---\n```\n\nFour fields, every page. Title and description for the head module and link previews. Slug for the URL and for wikilinks to find the page. Date for ordering and for the sitemap's `lastmod`.\n\nPer-page exceptions go here too. If a single post needs a different layout, declare `layout` in its front matter; the cascade picks the more specific value.\n\n---\n\n## The two layers meet at the permalink\n\nThe cleanest place to see the split is the permalink function. It reads `slug` from front matter and the structural keys from the data file, and composes the URL from both.\n\nA page in `src/content/blog/` with `slug: 'first-post'` and `section: ['blog']` resolves to `/blog/first-post/`.\n\nExtend `section` to `['blog', '2026']` and every page in the folder gets `/blog/2026/<slug>/` without each post having to spell out its own path. The array is the path – nest as deep as your site needs.\n\n```js\n// src/content/blog/blog.11tydata.js\nexport default {\n\t// permalink (covered below)\n\tpermalink: function (data) {\n\t\tconst { slug, page, section } = data;\n\n\t\t// Don't try to render the data file itself as a page.\n\t\tif (page.inputPath.includes('11tydata.js')) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Front-matter slug wins; otherwise fall back to the file's own slug.\n\t\tconst slugified = slug ? this.slugify(slug) : page.fileSlug;\n\n\t\t// Compose /<section[0]>/<section[1]>/.../<slug>/.\n\t\tconst parts = (section ?? []).map((part) => this.slugify(part));\n\t\tparts.push(slugified);\n\n\t\t// Leading slash anchors to the site root; trailing slash is the project convention.\n\t\treturn '/' + parts.join('/') + '/';\n\t}\n};\n```\n\n---\n\n## Adding a language prefix\n\nFor a multilingual site, the permalink needs one more step: prefix the URL with the language code, except for the default language which sits at the site root.\n\nThe signal comes from two places already in the cascade. `data.lang` is set per language tree (typically in `en.11tydata.js`, `nl.11tydata.js`, and so on). `data.settings.defaultLanguage` lives in `_data/settings.js` and names the language that owns the root.\n\nDrop the data file one level up, at the top of your content tree, so its values cascade to every section underneath:\n\n```js\n// src/content/content.11tydata.js\nexport default {\n\tpermalink: function (data) {\n\t\t// Don't try to render the data file itself as a page.\n\t\tif (data.page.inputPath.includes('11tydata.js')) return false;\n\n\t\t// Front-matter slug wins; otherwise fall back to the file's own slug.\n\t\tconst slug = data.slug ? this.slugify(data.slug) : data.page.fileSlug;\n\n\t\t// Prefix non-default languages; default language and single-language sites sit at root.\n\t\tconst isDefaultLang = !data.lang || data.lang === data.settings?.defaultLanguage;\n\t\tconst prefix = isDefaultLang ? '' : `/${data.lang}`;\n\n\t\t// Compose /<section[0]>/<section[1]>/.../<slug>/, with optional language prefix.\n\t\tconst sections = (data.section ?? []).map((s) => this.slugify(s));\n\t\treturn `${prefix}/${[...sections, slug].join('/')}/`;\n\t}\n};\n```\n\nA page with `lang: 'en'` on a site whose `defaultLanguage` is `'en'` resolves to `/blog/first-post/`. The same page with `lang: 'nl'` resolves to `/nl/blog/first-post/`. A single-language site leaves `lang` unset and never sees a prefix.\n\nThe optional chaining on `data.settings?.defaultLanguage` keeps the check safe when `settings` or `defaultLanguage` isn't defined, which is the single-language case.\n\n---\n\n## Worth knowing\n\n- **`section` is always an array.** Even a one-level section is written as `['blog']`. The shape teaches the path-like nature of the field and lets you nest deeper without restructuring later.\n- **Front matter overrides the data file.** Eleventy resolves to the more specific value, so a single page can opt out of any default by declaring it in front matter.\n- **The data file isn't a page.** The `inputPath.includes('11tydata.js')` check returns `false` from the permalink so Eleventy doesn't try to render it.\n- **Paths use a leading slash.** Without it, the permalink resolves relative to the input subdirectory rather than the site root.\n\n---\n\n## Opting out\n\nA page can exist and render without showing up in indexes. Two keys cover the common cases – one Baseline, one Eleventy-native – and either works from front matter or the data file:\n\n```yaml\n---\nbaselineExcludeFromGraph: true        # keep this page out of the content graph\neleventyExcludeFromCollections: true  # keep this page out of all Eleventy collections\n---\n```\n\n`baselineExcludeFromGraph` is read by the content graph's prepass; the page still renders, but nothing the graph feeds (navigator listings, sitemap, related-page surfaces) will see it.\n\n`eleventyExcludeFromCollections` is Eleventy's built-in opt-out from `collections.all` and any tagged collection – reach for it when a page needs to render but shouldn't be picked up by any iteration over collections.\n\n---\n\n## See also\n\n- [[project-structure]] for the project-shape conventions this pattern slots into.\n- [[page-context|Page context]] reference for what Baseline reads off each page at cascade time.\n",
             url: '/docs/concept/content-organisation/',
             outputPath: './dist/docs/concept/content-organisation/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-05-02T00:00:00.000Z,
             dateModified: 2026-06-04T18:03:33.000Z },
          inputPath: './src/content/docs/01.concept/03.content-organisation.md',
          fileSlug: '03.content-organisation',
          filePathStem: '/content/docs/01.concept/03.content-organisation',
          date: 2026-05-02T00:00:00.000Z,
          outputPath: './dist/docs/concept/content-organisation/index.html',
          url: '/docs/concept/content-organisation/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/01.concept/04.content-helpers.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '04.content-helpers',
             filePathStem: '/content/docs/01.concept/04.content-helpers',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThis section covers the small but important pieces that keep content predictable as it scales.\n\nTogether, these helpers define how content moves through the system without adding friction or hidden behavior.\n\n---\n\n## Drafts\n\nAny page with `draft: true` in front matter is dropped on `build` and kept on `serve`. The preprocessor is on automatically; you don\'t register it. Use it for in-progress pages you want to preview locally without shipping.\n\n```yaml\n---\ntitle: \'Half-written thoughts\'\ndraft: true\n---\n```\n\n---\n\n## Wikilinks\n\nForward links, MediaWiki-style. All resolved at render time, all combinable:\n\n- `[[slug]]` links to the page with that slug. The link text defaults to the page\'s title.\n- `[[slug#anchor]]` links to a heading on that page. The anchor is slugified for you.\n- `[[slug:lang]]` hops to the translation in the named language (BCP47 code, e.g. `[[about:fr]]`).\n- `[[slug|alias]]` sets custom link text. The pipe is the alias separator.\n\nThe forms compose. `[[about:fr#team|notre equipe]]` is valid. Misses (unknown slug, missing translation) render as the original literal text rather than a broken link, so a typo is visible without crashing the build.\n\nSlugs are global within the default language. Wikilinks themselves are forward-only; the content-graph pre-pass does build a reverse index, exposed as `data._backlinks` per page and `_navigator.backlinks` site-wide, so authors can opt in to "what links here" surfaces without the wikilink syntax sprouting them automatically.\n\nCurated cross-references still win over automatic ones in narrative prose.\n\n---\n\n### Where they work\n\nWikilinks are a markdown-it inline rule, so they resolve in `.md` body content only. They do not run in Nunjucks templates or in front matter values. If you need a link from a layout or a data field, write the URL directly.\n\n---\n\n## Heading IDs\n\nEvery heading in your Markdown gets a stable `id` attribute automatically. The id is the slugified heading text, so `## Implementation details` becomes `<h2 id="implementation-details">`. You can link to it directly with `#implementation-details`, and `_node.headings` carries the same id so a generated table of contents matches the anchors it points at.\n\nRepeated headings dedup with WordPress-style numeric suffixes: the first stays `foo`, the second becomes `foo-2`, the third `foo-3`, and so on. Stable across builds for the same source order.\n\n---\n\n### Overriding an id\n\nA manual id wins over the auto one. Use the attribute syntax described below:\n\n{% raw %}\n\n```markdown\n## Implementation details {#impl}\n```\n\n{% endraw %}\n\nRenders as `<h2 id="impl">`. Manual ids are also seeded into the dedup map, so a later heading with the same slugified text gets the next free name (`implementation-details` here, since `impl` does not collide).\n\n---\n\n### Why one source\n\nHeading ids live in two places that need to agree: the rendered HTML you anchor links to, and the `headings[].id` field on the content graph that templates read for a TOC. They are assigned once in the markdown engine; the rendered HTML and the graph read the same id back. No drift between "the link" and "the table of contents entry".\n\n---\n\n## Element attributes\n\nThe {% raw %}`{#id .class key="value"}`{% endraw %} syntax attaches attributes to any block element. It runs through the upstream `markdown-it-attrs` plugin, which Baseline ships as a direct dependency.\n\n{% raw %}\n\n```markdown\n## A section heading {#impl .lead}\n\nA paragraph with a class. {.note}\n\n![Alt text](/img/hero.jpg){#hero loading="eager"}\n```\n\n{% endraw %}\n\nThe attributes attach to the element that ended just before them. Useful for adding a class to a paragraph, anchoring a heading with a specific id, or marking an image so a transform can find it later.\n\nLoaded under `safeUse`, so if you already wired `markdown-it-attrs` yourself with different options, your registration wins and Baseline\'s is skipped silently.\n\nThe same dedup applies to the heading-id and wikilinks plugins; you can layer your own markdown extensions without fighting Baseline\'s wiring.\n\n---\n\n## Images\n\nThe shortcode is Baseline\'s. The heavier transform isn\'t.\n\n{% stepsBlock "compact" %}\n\n- {% raw %}`{% image %}`{% endraw %} is always registered. `eleventy-img` is a peer dep that ships with Baseline.\n- AVIF and WebP by default. No JPEG fallback. Modern browsers handle these and the file size difference is real.\n- The HTML transform that rewrites `<img>` into responsive `<picture>` (`eleventyImageTransformPlugin`) is opt-in. You add it yourself if you want it. When it is present, the shortcode marks its own output with `eleventy:ignore` to avoid double-processing.\n\n{% endstepsBlock %}\n\nAlt text matters. The shortcode warns when it is missing (use an empty string for decorative images). The [[image-transform | image transform]] how-to walks you through the responsive pipeline.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Concept',
             title: 'Content helpers',
             slug: 'content-helpers',
             description:
              'How drafts, wikilinks, heading IDs, element attributes, and image handling work in Baseline, and the rules that keep content predictable.',
             date: 2026-05-02T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/01.concept/04.content-helpers.md',
             fileSlug: '04.content-helpers',
             filePathStem: '/content/docs/01.concept/04.content-helpers',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-02T00:00:00.000Z,
             rawInput:
              '\nThis section covers the small but important pieces that keep content predictable as it scales.\n\nTogether, these helpers define how content moves through the system without adding friction or hidden behavior.\n\n---\n\n## Drafts\n\nAny page with `draft: true` in front matter is dropped on `build` and kept on `serve`. The preprocessor is on automatically; you don\'t register it. Use it for in-progress pages you want to preview locally without shipping.\n\n```yaml\n---\ntitle: \'Half-written thoughts\'\ndraft: true\n---\n```\n\n---\n\n## Wikilinks\n\nForward links, MediaWiki-style. All resolved at render time, all combinable:\n\n- `[[slug]]` links to the page with that slug. The link text defaults to the page\'s title.\n- `[[slug#anchor]]` links to a heading on that page. The anchor is slugified for you.\n- `[[slug:lang]]` hops to the translation in the named language (BCP47 code, e.g. `[[about:fr]]`).\n- `[[slug|alias]]` sets custom link text. The pipe is the alias separator.\n\nThe forms compose. `[[about:fr#team|notre equipe]]` is valid. Misses (unknown slug, missing translation) render as the original literal text rather than a broken link, so a typo is visible without crashing the build.\n\nSlugs are global within the default language. Wikilinks themselves are forward-only; the content-graph pre-pass does build a reverse index, exposed as `data._backlinks` per page and `_navigator.backlinks` site-wide, so authors can opt in to "what links here" surfaces without the wikilink syntax sprouting them automatically.\n\nCurated cross-references still win over automatic ones in narrative prose.\n\n---\n\n### Where they work\n\nWikilinks are a markdown-it inline rule, so they resolve in `.md` body content only. They do not run in Nunjucks templates or in front matter values. If you need a link from a layout or a data field, write the URL directly.\n\n---\n\n## Heading IDs\n\nEvery heading in your Markdown gets a stable `id` attribute automatically. The id is the slugified heading text, so `## Implementation details` becomes `<h2 id="implementation-details">`. You can link to it directly with `#implementation-details`, and `_node.headings` carries the same id so a generated table of contents matches the anchors it points at.\n\nRepeated headings dedup with WordPress-style numeric suffixes: the first stays `foo`, the second becomes `foo-2`, the third `foo-3`, and so on. Stable across builds for the same source order.\n\n---\n\n### Overriding an id\n\nA manual id wins over the auto one. Use the attribute syntax described below:\n\n{% raw %}\n\n```markdown\n## Implementation details {#impl}\n```\n\n{% endraw %}\n\nRenders as `<h2 id="impl">`. Manual ids are also seeded into the dedup map, so a later heading with the same slugified text gets the next free name (`implementation-details` here, since `impl` does not collide).\n\n---\n\n### Why one source\n\nHeading ids live in two places that need to agree: the rendered HTML you anchor links to, and the `headings[].id` field on the content graph that templates read for a TOC. They are assigned once in the markdown engine; the rendered HTML and the graph read the same id back. No drift between "the link" and "the table of contents entry".\n\n---\n\n## Element attributes\n\nThe {% raw %}`{#id .class key="value"}`{% endraw %} syntax attaches attributes to any block element. It runs through the upstream `markdown-it-attrs` plugin, which Baseline ships as a direct dependency.\n\n{% raw %}\n\n```markdown\n## A section heading {#impl .lead}\n\nA paragraph with a class. {.note}\n\n![Alt text](/img/hero.jpg){#hero loading="eager"}\n```\n\n{% endraw %}\n\nThe attributes attach to the element that ended just before them. Useful for adding a class to a paragraph, anchoring a heading with a specific id, or marking an image so a transform can find it later.\n\nLoaded under `safeUse`, so if you already wired `markdown-it-attrs` yourself with different options, your registration wins and Baseline\'s is skipped silently.\n\nThe same dedup applies to the heading-id and wikilinks plugins; you can layer your own markdown extensions without fighting Baseline\'s wiring.\n\n---\n\n## Images\n\nThe shortcode is Baseline\'s. The heavier transform isn\'t.\n\n{% stepsBlock "compact" %}\n\n- {% raw %}`{% image %}`{% endraw %} is always registered. `eleventy-img` is a peer dep that ships with Baseline.\n- AVIF and WebP by default. No JPEG fallback. Modern browsers handle these and the file size difference is real.\n- The HTML transform that rewrites `<img>` into responsive `<picture>` (`eleventyImageTransformPlugin`) is opt-in. You add it yourself if you want it. When it is present, the shortcode marks its own output with `eleventy:ignore` to avoid double-processing.\n\n{% endstepsBlock %}\n\nAlt text matters. The shortcode warns when it is missing (use an empty string for decorative images). The [[image-transform | image transform]] how-to walks you through the responsive pipeline.\n',
             url: '/docs/concept/content-helpers/',
             outputPath: './dist/docs/concept/content-helpers/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-05-02T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/01.concept/04.content-helpers.md',
          fileSlug: '04.content-helpers',
          filePathStem: '/content/docs/01.concept/04.content-helpers',
          date: 2026-05-02T00:00:00.000Z,
          outputPath: './dist/docs/concept/content-helpers/index.html',
          url: '/docs/concept/content-helpers/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/01.concept/05.architecture-snapshot.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '05.architecture-snapshot',
             filePathStem: '/content/docs/01.concept/05.architecture-snapshot',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThe plugin is built in three concentric layers, each with one strict job.\n\nYou almost never notice the boundary in day-to-day work, but it explains a lot of "why does this thing live here and not there" once you know it.\n\nThis is the deeper read. If you just want to ship, the [[quickstart | quickstart]] is enough; this page is for when you want to understand what is going on under it.\n\n---\n\n## Why look at it this way\n\nThe split responds to a structural seam in Eleventy itself. Data resolves through the cascade, templates render, then a separate transform phase writes HTML to disk with no native channel back to what the cascade produced.\n\nA few Eleventy surfaces are also closed by design (the directory map only honours its built-in keys).\n\nThe runtime layer is the bridge: registry-scoped stores that capture cascade-time values and hand them out on demand.\n\nNaming the three layers keeps the bridge clean. **State** is what the user said; **runtime** is what the build is currently doing; **modules** are what each feature does with both.\n\nEach has one input, one output, and no other way to talk to the others.\n\n{% alertBlock %}\n\n**The line worth keeping in mind:**  \nCascade-time work is plain Eleventy data; transform-time work has access to everything the cascade produced; modules stay out of each other\'s way.\n\n{% endalertBlock %}\n\n---\n\n## The three layers\n\n---\n\n### State\n\n> State is your input, normalised.\n\nWhatever you pass to `baseline(settings, options)` gets validated, defaulted, and shaped into the canonical form the rest of the plugin reads from.\n\nTwo top-level objects:\n\n- **`state.settings`**: site identity. Title, tagline, url, languages, the `head` extras object. The things a designer or content author would name.\n- **`state.options`**: runtime flags. Which optional modules are on, log verbosity, fine-grained module options like `head.titleSeparator` or `assets.esbuild`.\n\nState is computed once, at plugin-init, and treated as immutable from that point on. Modules read it; nothing writes back.\n\nTemplates see one slice of state: the **`_baseline`** global, exposed as `_baseline.{ env, features, paths }`:\n\n- `env`: package name, version, and the resolved `ELEVENTY_ENV` mode.\n- `features`: the resolved `state.options` plus a couple of derived flags (for example, whether `eleventyImageTransformPlugin` is loaded).\n- `paths`: the directory map, including the asymmetric `paths.public` (the virtual key) versus `paths.assets` (also virtual), built from the resolved `eleventyConfig.directories`.\n\nThe [[globals | globals reference]] covers the exact shape; the [[plugin-entrypoint | plugin entrypoint]] reference covers the option list that feeds into it.\n\n---\n\n### Runtime\n\n> Runtime is the lazy access layer over Eleventy\'s lifecycle.\n\nIt is where the things that are not knowable at plugin-init live: the templates Eleventy is going to build, the relationships between translated pages, the resolved per-page data.\n\nThree pieces matter:\n\n- **The content map.** Every template Eleventy sees during the build, available through a getter. Populated by the `eleventy.contentMap` event; modules read it without subscribing to events themselves.\n- **The translation map.** Which pages are translations of which. Written by `multilang` when it is active; read by `head` (for hreflang) and `sitemap` (for per-language sitemap routing).\n- **The page context.** A normalised per-page object built at cascade-time and cached for transform-time. The user-visible surface is the `_pageContext` global; the [[page-context | page context]] reference covers the full shape.\n\nThe point of runtime is that **modules read through getters, never by direct event subscription**. A module asks "what is the translation map right now?" and the runtime resolves it.\n\nIf the answer is not ready yet, that is a bug in the calling code, not a race condition between modules. The decoupling is structural.\n\nA small set of cross-cutting primitives sits underneath:\n\n- The **registry** is the scope primitive (per-config cache, values map, listener dedup). It is the substrate the content-map store, translation-map store, and page-context registry sit on.\n- **Virtual directories** are Baseline-synthesised keys on `eleventyConfig.directories` (the `assets` and `public` keys), mounted there because Eleventy\'s directory machinery only honours its fixed set. They read like any other directory key from a module\'s point of view.\n- **Stores** are the convention for runtime singletons attached to a registry scope (the content-map store, the translation-map store).\n\nThese are internals you can mostly ignore. The [[internals | internals]] reference covers them in case you hit one through the navigator.\n\n---\n\n### Modules\n\n> Modules are the five feature plugins layered on top of state and runtime.\n\n- **assets**: the asset pipeline.\n- **head**: replaces the `<baseline-head>` placeholder with the right tags.\n- **multilang**: directory-based multilingual support. Opt-in.\n- **navigator**: runtime-introspection tooling and the public read surface for plugin-produced cross-page data (`_navigator.nodes`, `_navigator.edges`, `_navigator.backlinks`). The `phpinfo()`-style virtual page is on in development by default; the read surface is always available.\n- **sitemap**: XML sitemap generation.\n\nEach is registered through a small declarative registry inside the plugin entry point, conditionally activated based on `state.options`.\n\nThey receive a uniform **module context** object: `{ env, state, runtime, directories, helpers, log, snapshots, resolvePageContext }`.\n\nThat object is the module\'s only window onto the plugin; nothing else is in scope. Modules never share state directly.\n\nIf `head` needs the translation map, it reads it from `runtime`. If `sitemap` needs to know which languages exist, it reads `state.settings`.\n\nThe contract is small and uniform on purpose. The full per-module reference lives in the [[module | modules]] chapter.\n\n---\n\n## How the layers communicate\n\nYour content and templates live in `src/content/` and `src/_includes/`.\n\nThe modules wrap around them: assets are compiled, head tags are injected, sitemaps are generated, hreflang is wired. Eleventy writes the result to `dist/`.\n\n> The runtime layer in this instance is the mediator.\n\n{% stepsBlock "compact" %}\n\n- **assets** wires PostCSS and esbuild to entry points under `src/assets/` and exposes inline filters (`inlinePostCSS`, `inlineESbuild`) for critical-path CSS or JS. It reads `state.options.assets.esbuild` and the `assets` virtual directory; it does not talk to other modules.\n- **head** runs in two stages. At cascade-time, the page-context builder produces a normalised `head` seed object from `state.settings.head` and the page\'s own front matter.\n\n  At transform-time, a PostHTML plugin reads those seeds, plus the translation map (when `multilang` is active) for hreflang alternates, and replaces `<baseline-head>` with a capo-sorted, deduped element list.\n\n- **multilang** populates the translation map and adds per-language collections, the i18n filters, and `eleventyComputed.page.locale`.\n\n  Activation requires explicit opt-in: `options.multilingual: true`, plus `settings.defaultLanguage`, plus a non-empty `settings.languages` map.\n\n- **navigator** exposes the `_runtime` and `_ctx` globals, the inspector filters (`_inspect`, `_json`, `_keys`), the `_snapshot` debug surface, and the `_navigator` global (`{ nodes, edges, backlinks }`) for cross-page reads of the [[content-graph | content graph]].\n\n  The snapshot reads from runtime stores so you can drop {% raw %}`{{ _snapshot.contentMap | _json }}`{% endraw %} into a template and see the build\'s current state. The `_navigator` global pairs with the per-page cascade keys `data._node`, `data._backlinks`, and `data._outgoing` for the same substrate at different scopes.\n\n- **sitemap** reads the content map, generates the XML, and (when multilang is on) produces per-language sitemaps plus an index.\n\n{% endstepsBlock %}\n\nThe cross-module link a careful reader will encounter is **head ↔ multilang via the translation map**. Multilang writes it; head reads it. Neither calls the other; runtime owns the data.\n\n---\n\n## Where to go next\n\n- The [[core-reference | core reference]] index for the lookup view of options, globals, filters, and the page context.\n- The [[page-context | page-context]] reference for the exact shape of the per-page object.\n- The [[internals | internals]] reference for the registry, stores, and virtual directories.\n- The [[module | modules]] chapter for what each feature plugin does and the options it accepts.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Concept',
             title: 'Architecture snapshot',
             description:
              'The three-layer model behind baseline: state, runtime, modules. Why it is built that way and how the layers talk to each other.',
             slug: 'architecture-snapshot',
             date: 2026-04-28T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/01.concept/05.architecture-snapshot.md',
             fileSlug: '05.architecture-snapshot',
             filePathStem: '/content/docs/01.concept/05.architecture-snapshot',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-04-28T00:00:00.000Z,
             rawInput:
              '\nThe plugin is built in three concentric layers, each with one strict job.\n\nYou almost never notice the boundary in day-to-day work, but it explains a lot of "why does this thing live here and not there" once you know it.\n\nThis is the deeper read. If you just want to ship, the [[quickstart | quickstart]] is enough; this page is for when you want to understand what is going on under it.\n\n---\n\n## Why look at it this way\n\nThe split responds to a structural seam in Eleventy itself. Data resolves through the cascade, templates render, then a separate transform phase writes HTML to disk with no native channel back to what the cascade produced.\n\nA few Eleventy surfaces are also closed by design (the directory map only honours its built-in keys).\n\nThe runtime layer is the bridge: registry-scoped stores that capture cascade-time values and hand them out on demand.\n\nNaming the three layers keeps the bridge clean. **State** is what the user said; **runtime** is what the build is currently doing; **modules** are what each feature does with both.\n\nEach has one input, one output, and no other way to talk to the others.\n\n{% alertBlock %}\n\n**The line worth keeping in mind:**  \nCascade-time work is plain Eleventy data; transform-time work has access to everything the cascade produced; modules stay out of each other\'s way.\n\n{% endalertBlock %}\n\n---\n\n## The three layers\n\n---\n\n### State\n\n> State is your input, normalised.\n\nWhatever you pass to `baseline(settings, options)` gets validated, defaulted, and shaped into the canonical form the rest of the plugin reads from.\n\nTwo top-level objects:\n\n- **`state.settings`**: site identity. Title, tagline, url, languages, the `head` extras object. The things a designer or content author would name.\n- **`state.options`**: runtime flags. Which optional modules are on, log verbosity, fine-grained module options like `head.titleSeparator` or `assets.esbuild`.\n\nState is computed once, at plugin-init, and treated as immutable from that point on. Modules read it; nothing writes back.\n\nTemplates see one slice of state: the **`_baseline`** global, exposed as `_baseline.{ env, features, paths }`:\n\n- `env`: package name, version, and the resolved `ELEVENTY_ENV` mode.\n- `features`: the resolved `state.options` plus a couple of derived flags (for example, whether `eleventyImageTransformPlugin` is loaded).\n- `paths`: the directory map, including the asymmetric `paths.public` (the virtual key) versus `paths.assets` (also virtual), built from the resolved `eleventyConfig.directories`.\n\nThe [[globals | globals reference]] covers the exact shape; the [[plugin-entrypoint | plugin entrypoint]] reference covers the option list that feeds into it.\n\n---\n\n### Runtime\n\n> Runtime is the lazy access layer over Eleventy\'s lifecycle.\n\nIt is where the things that are not knowable at plugin-init live: the templates Eleventy is going to build, the relationships between translated pages, the resolved per-page data.\n\nThree pieces matter:\n\n- **The content map.** Every template Eleventy sees during the build, available through a getter. Populated by the `eleventy.contentMap` event; modules read it without subscribing to events themselves.\n- **The translation map.** Which pages are translations of which. Written by `multilang` when it is active; read by `head` (for hreflang) and `sitemap` (for per-language sitemap routing).\n- **The page context.** A normalised per-page object built at cascade-time and cached for transform-time. The user-visible surface is the `_pageContext` global; the [[page-context | page context]] reference covers the full shape.\n\nThe point of runtime is that **modules read through getters, never by direct event subscription**. A module asks "what is the translation map right now?" and the runtime resolves it.\n\nIf the answer is not ready yet, that is a bug in the calling code, not a race condition between modules. The decoupling is structural.\n\nA small set of cross-cutting primitives sits underneath:\n\n- The **registry** is the scope primitive (per-config cache, values map, listener dedup). It is the substrate the content-map store, translation-map store, and page-context registry sit on.\n- **Virtual directories** are Baseline-synthesised keys on `eleventyConfig.directories` (the `assets` and `public` keys), mounted there because Eleventy\'s directory machinery only honours its fixed set. They read like any other directory key from a module\'s point of view.\n- **Stores** are the convention for runtime singletons attached to a registry scope (the content-map store, the translation-map store).\n\nThese are internals you can mostly ignore. The [[internals | internals]] reference covers them in case you hit one through the navigator.\n\n---\n\n### Modules\n\n> Modules are the five feature plugins layered on top of state and runtime.\n\n- **assets**: the asset pipeline.\n- **head**: replaces the `<baseline-head>` placeholder with the right tags.\n- **multilang**: directory-based multilingual support. Opt-in.\n- **navigator**: runtime-introspection tooling and the public read surface for plugin-produced cross-page data (`_navigator.nodes`, `_navigator.edges`, `_navigator.backlinks`). The `phpinfo()`-style virtual page is on in development by default; the read surface is always available.\n- **sitemap**: XML sitemap generation.\n\nEach is registered through a small declarative registry inside the plugin entry point, conditionally activated based on `state.options`.\n\nThey receive a uniform **module context** object: `{ env, state, runtime, directories, helpers, log, snapshots, resolvePageContext }`.\n\nThat object is the module\'s only window onto the plugin; nothing else is in scope. Modules never share state directly.\n\nIf `head` needs the translation map, it reads it from `runtime`. If `sitemap` needs to know which languages exist, it reads `state.settings`.\n\nThe contract is small and uniform on purpose. The full per-module reference lives in the [[module | modules]] chapter.\n\n---\n\n## How the layers communicate\n\nYour content and templates live in `src/content/` and `src/_includes/`.\n\nThe modules wrap around them: assets are compiled, head tags are injected, sitemaps are generated, hreflang is wired. Eleventy writes the result to `dist/`.\n\n> The runtime layer in this instance is the mediator.\n\n{% stepsBlock "compact" %}\n\n- **assets** wires PostCSS and esbuild to entry points under `src/assets/` and exposes inline filters (`inlinePostCSS`, `inlineESbuild`) for critical-path CSS or JS. It reads `state.options.assets.esbuild` and the `assets` virtual directory; it does not talk to other modules.\n- **head** runs in two stages. At cascade-time, the page-context builder produces a normalised `head` seed object from `state.settings.head` and the page\'s own front matter.\n\n  At transform-time, a PostHTML plugin reads those seeds, plus the translation map (when `multilang` is active) for hreflang alternates, and replaces `<baseline-head>` with a capo-sorted, deduped element list.\n\n- **multilang** populates the translation map and adds per-language collections, the i18n filters, and `eleventyComputed.page.locale`.\n\n  Activation requires explicit opt-in: `options.multilingual: true`, plus `settings.defaultLanguage`, plus a non-empty `settings.languages` map.\n\n- **navigator** exposes the `_runtime` and `_ctx` globals, the inspector filters (`_inspect`, `_json`, `_keys`), the `_snapshot` debug surface, and the `_navigator` global (`{ nodes, edges, backlinks }`) for cross-page reads of the [[content-graph | content graph]].\n\n  The snapshot reads from runtime stores so you can drop {% raw %}`{{ _snapshot.contentMap | _json }}`{% endraw %} into a template and see the build\'s current state. The `_navigator` global pairs with the per-page cascade keys `data._node`, `data._backlinks`, and `data._outgoing` for the same substrate at different scopes.\n\n- **sitemap** reads the content map, generates the XML, and (when multilang is on) produces per-language sitemaps plus an index.\n\n{% endstepsBlock %}\n\nThe cross-module link a careful reader will encounter is **head ↔ multilang via the translation map**. Multilang writes it; head reads it. Neither calls the other; runtime owns the data.\n\n---\n\n## Where to go next\n\n- The [[core-reference | core reference]] index for the lookup view of options, globals, filters, and the page context.\n- The [[page-context | page-context]] reference for the exact shape of the per-page object.\n- The [[internals | internals]] reference for the registry, stores, and virtual directories.\n- The [[module | modules]] chapter for what each feature plugin does and the options it accepts.\n',
             url: '/docs/concept/architecture-snapshot/',
             outputPath: './dist/docs/concept/architecture-snapshot/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-04-28T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/01.concept/05.architecture-snapshot.md',
          fileSlug: '05.architecture-snapshot',
          filePathStem: '/content/docs/01.concept/05.architecture-snapshot',
          date: 2026-04-28T00:00:00.000Z,
          outputPath: './dist/docs/concept/architecture-snapshot/index.html',
          url: '/docs/concept/architecture-snapshot/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        ... 35 more items ],
     faq:
      [ { template:
           Template {
             inputPath: './src/content/faq/01-lock-in.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '01-lock-in',
             filePathStem: '/content/faq/01-lock-in',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             _stats: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           "\nNo. It's a standard Eleventy plugin. Take it out and your Eleventy site still builds: you keep your content, your config, your output. Baseline adds conventions and wiring, not a cage.\n",
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: false,
             layout: false,
             title: 'Does Baseline lock me in?',
             order: 1,
             answer:
              "No. It's a standard Eleventy plugin. Take it out and your Eleventy site still builds: you keep your content, your config, your output. Baseline adds conventions and wiring, not a cage.\n",
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: undefined,
             _backlinks: [],
             _outgoing: [],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/faq/01-lock-in.md',
             fileSlug: '01-lock-in',
             filePathStem: '/content/faq/01-lock-in',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-06-08T15:47:17.070Z,
             rawInput:
              "\nNo. It's a standard Eleventy plugin. Take it out and your Eleventy site still builds: you keep your content, your config, your output. Baseline adds conventions and wiring, not a cage.\n",
             url: false,
             outputPath: false,
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-06-08T15:47:17.070Z,
             dateModified: 2026-06-03T09:37:58.000Z },
          inputPath: './src/content/faq/01-lock-in.md',
          fileSlug: '01-lock-in',
          filePathStem: '/content/faq/01-lock-in',
          date: 2026-06-08T15:47:17.070Z,
          outputPath: false,
          url: false,
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/faq/02-vs-eleventy.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '02-vs-eleventy',
             filePathStem: '/content/faq/02-vs-eleventy',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             _stats: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           "\nEleventy gives you the engine and gets out of your way, which is its whole appeal. Baseline is the setup you'd otherwise wire by hand on every project, the head, the assets pipeline, multilingual routing, sitemaps, an SEO graph, crystallised into one plugin. You could write it yourself. This is the version that's already written.\n",
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: false,
             layout: false,
             title: "Doesn't Eleventy already do all this?",
             order: 2,
             answer:
              "Eleventy gives you the engine and gets out of your way, which is its whole appeal. Baseline is the setup you'd otherwise wire by hand on every project, the head, the assets pipeline, multilingual routing, sitemaps, an SEO graph, crystallised into one plugin. You could write it yourself. This is the version that's already written.\n",
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: undefined,
             _backlinks: [],
             _outgoing: [],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/faq/02-vs-eleventy.md',
             fileSlug: '02-vs-eleventy',
             filePathStem: '/content/faq/02-vs-eleventy',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-06-08T15:47:17.070Z,
             rawInput:
              "\nEleventy gives you the engine and gets out of your way, which is its whole appeal. Baseline is the setup you'd otherwise wire by hand on every project, the head, the assets pipeline, multilingual routing, sitemaps, an SEO graph, crystallised into one plugin. You could write it yourself. This is the version that's already written.\n",
             url: false,
             outputPath: false,
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-06-08T15:47:17.070Z,
             dateModified: 2026-06-03T09:37:58.000Z },
          inputPath: './src/content/faq/02-vs-eleventy.md',
          fileSlug: '02-vs-eleventy',
          filePathStem: '/content/faq/02-vs-eleventy',
          date: 2026-06-08T15:47:17.070Z,
          outputPath: false,
          url: false,
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/faq/03-production-ready.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '03-production-ready',
             filePathStem: '/content/faq/03-production-ready',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             _stats: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           "\nIt's pre-1.0 and ships on a rolling 0.1.0-next.X cadence, so pin a version when you build something you care about. The ground it covers is stable and demonstrated on this very site, which runs on Baseline.\n",
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: false,
             layout: false,
             title: 'Is it production-ready?',
             order: 3,
             answer:
              "It's pre-1.0 and ships on a rolling 0.1.0-next.X cadence, so pin a version when you build something you care about. The ground it covers is stable and demonstrated on this very site, which runs on Baseline.\n",
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: undefined,
             _backlinks: [],
             _outgoing: [],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/faq/03-production-ready.md',
             fileSlug: '03-production-ready',
             filePathStem: '/content/faq/03-production-ready',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-06-08T15:47:17.070Z,
             rawInput:
              "\nIt's pre-1.0 and ships on a rolling 0.1.0-next.X cadence, so pin a version when you build something you care about. The ground it covers is stable and demonstrated on this very site, which runs on Baseline.\n",
             url: false,
             outputPath: false,
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-06-08T15:47:17.070Z,
             dateModified: 2026-06-03T09:37:58.000Z },
          inputPath: './src/content/faq/03-production-ready.md',
          fileSlug: '03-production-ready',
          filePathStem: '/content/faq/03-production-ready',
          date: 2026-06-08T15:47:17.070Z,
          outputPath: false,
          url: false,
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/faq/04-own-tooling.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '04-own-tooling',
             filePathStem: '/content/faq/04-own-tooling',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             _stats: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           "\nYes. The assets pipeline is a convention, not a lock: one CSS entry through PostCSS, one JS entry through esbuild, and you say where they load. Don't want it? Don't use it; the rest of Baseline doesn't mind.\n",
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: false,
             layout: false,
             title: 'Can I bring my own CSS and JS setup?',
             order: 4,
             answer:
              "Yes. The assets pipeline is a convention, not a lock: one CSS entry through PostCSS, one JS entry through esbuild, and you say where they load. Don't want it? Don't use it; the rest of Baseline doesn't mind.\n",
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: undefined,
             _backlinks: [],
             _outgoing: [],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/faq/04-own-tooling.md',
             fileSlug: '04-own-tooling',
             filePathStem: '/content/faq/04-own-tooling',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-06-08T15:47:17.070Z,
             rawInput:
              "\nYes. The assets pipeline is a convention, not a lock: one CSS entry through PostCSS, one JS entry through esbuild, and you say where they load. Don't want it? Don't use it; the rest of Baseline doesn't mind.\n",
             url: false,
             outputPath: false,
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-06-08T15:47:17.070Z,
             dateModified: 2026-06-03T09:37:58.000Z },
          inputPath: './src/content/faq/04-own-tooling.md',
          fileSlug: '04-own-tooling',
          filePathStem: '/content/faq/04-own-tooling',
          date: 2026-06-08T15:47:17.070Z,
          outputPath: false,
          url: false,
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/faq/05-seo.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '05-seo',
             filePathStem: '/content/faq/05-seo',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             _stats: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nIt builds a complete schema.org graph for every page, wired with stable @id values, plus Open Graph, Twitter cards, and canonicals. You author identity once and add custom nodes through one seam. (This FAQ is one of those custom nodes.)\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: false,
             layout: false,
             title: 'What does it do for SEO?',
             order: 5,
             answer:
              'It builds a complete schema.org graph for every page, wired with stable @id values, plus Open Graph, Twitter cards, and canonicals. You author identity once and add custom nodes through one seam. (This FAQ is one of those custom nodes.)\n',
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: undefined,
             _backlinks: [],
             _outgoing: [],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/faq/05-seo.md',
             fileSlug: '05-seo',
             filePathStem: '/content/faq/05-seo',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-06-08T15:47:17.070Z,
             rawInput:
              '\nIt builds a complete schema.org graph for every page, wired with stable @id values, plus Open Graph, Twitter cards, and canonicals. You author identity once and add custom nodes through one seam. (This FAQ is one of those custom nodes.)\n',
             url: false,
             outputPath: false,
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-06-08T15:47:17.070Z,
             dateModified: 2026-06-03T09:37:58.000Z },
          inputPath: './src/content/faq/05-seo.md',
          fileSlug: '05-seo',
          filePathStem: '/content/faq/05-seo',
          date: 2026-06-08T15:47:17.070Z,
          outputPath: false,
          url: false,
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/faq/06-commercial-support.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '06-commercial-support',
             filePathStem: '/content/faq/06-commercial-support',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             _stats: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nYes. Baseline is built and maintained by a pleasant view. For priority help, a custom integration, or a site built on it, get in touch at hello@apleasantview.com.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: false,
             layout: false,
             title: 'Can I get commercial support?',
             order: 6,
             answer:
              'Yes. Baseline is built and maintained by a pleasant view. For priority help, a custom integration, or a site built on it, get in touch at hello@apleasantview.com.\n',
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: undefined,
             _backlinks: [],
             _outgoing: [],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/faq/06-commercial-support.md',
             fileSlug: '06-commercial-support',
             filePathStem: '/content/faq/06-commercial-support',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-06-08T15:47:17.070Z,
             rawInput:
              '\nYes. Baseline is built and maintained by a pleasant view. For priority help, a custom integration, or a site built on it, get in touch at hello@apleasantview.com.\n',
             url: false,
             outputPath: false,
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-06-08T15:47:17.070Z,
             dateModified: 2026-06-03T09:37:58.000Z },
          inputPath: './src/content/faq/06-commercial-support.md',
          fileSlug: '06-commercial-support',
          filePathStem: '/content/faq/06-commercial-support',
          date: 2026-06-08T15:47:17.070Z,
          outputPath: false,
          url: false,
          templateContent: [Getter/Setter],
          content: [Getter/Setter] } ],
     translationsMap:
      { about:
         { en:
            { title: 'About Eleventy Baseline',
              url: '/about/',
              lang: 'en',
              isDefaultLang: true,
              data: [Object] } },
        homepage:
         { en:
            { title: 'Eleventy Baseline',
              url: '/',
              lang: 'en',
              isDefaultLang: true,
              data: [Object] },
           fr:
            { title: 'Eleventy Baseline',
              url: '/fr/',
              lang: 'fr',
              isDefaultLang: false,
              data: [Object] },
           nl:
            { title: 'Eleventy Baseline',
              url: '/nl/',
              lang: 'nl',
              isDefaultLang: false,
              data: [Object] } } },
     translations:
      [ { template:
           Template {
             inputPath: './src/content/en/pages/about.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: 'about',
             filePathStem: '/content/en/pages/about',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\n_Baseline is an opinionated Eleventy plugin that handles the structural decisions you\'d otherwise wire up on every project. Looking for the marketing pitch? It\'s over on the [docs overview](https://www.eleventy-baseline.dev/docs/introduction/overview/)._\n\n_This page is the longer, more honest story._\n\n---\n\n## From starter to plugin\n\nBaseline started as my hundredth attempt at making a starter for client work, this time trying to be properly serious about it. The first version sat dormant for a while, but I kept coming back to it. It had one eye on the patterns and tooling already (silently) established in the Eleventy community.\n\nThe other eye was on what was missing for me: keeping client sites in sync without copying and rewriting files across projects, the per-language sitemaps I missed from Hugo, the single settings shape that WordPress gets right.\n\nThe shape clicked while I was thinking about something Zach Leatherman, Eleventy\'s creator, has said: that everything in Eleventy is essentially a plugin. I\'m paraphrasing, but that was the moment it stopped being a starter in my head.\n\nThe rewrite landed on the 1st of December 2025 as a single commit, "Rewrite baseline as a plugin." I announced the project on the Eleventy Discord shortly after, on the chance it might be useful to other people too.\n\nThat shift changed what the project needed to be. A personal starter can be implicit. You know why things are the way they are because you put them there. A plugin can\'t coast on that. Other people need to understand the choices, or at least trust them enough to get started.\n\nThe system has grown through use. Modules added when the project needed them, each with its own decisions, each leaning on the others. The starter became a system. Gradually, then all at once.\n\nThe framing shifted along with it. The earlier description called Baseline a "thin, optional wiring layer." That was true once. By April 2026 it had become an opinionated starting point. The value isn\'t that it\'s thin. The value is that these decisions are made, they work together, and the path to change one is clear when you disagree.\n\nWhat\'s in Baseline now is most of what I\'ve learned about building with Eleventy, and underneath that, fifteen years of working in tech, mostly but not only on the web. The decisions, the workarounds, the small conveniences that compound over hundreds of pages.\n\nIt evolved into its own thing along the way, but it grew out of an itch every Eleventy developer recognises: wiring up the same things on the third new project and wondering if there\'s a better way to keep that work.\n\nPutting the knowledge into code is the easier half. Finding the right shape for it, what to name, what to group, what belongs in the plugin and what belongs in the docs, is the harder one, and it\'s still in motion.\n\nToday Baseline is a working plugin handling structural decisions for an Eleventy project: things like responsive image widths, the head tags every site needs, per-language sitemaps with `x-default`, drafts kept out of production.\n\nIt ships continuously on npm as `0.1.0-next.X` and runs in production on its own docs site, on [a pleasant view](https://www.apleasantview.com), and on client sites. The code is stable. The architecture is settled. The words around it are still catching up.\n\n---\n\n## Eleventy and the educational gap\n\nAround the time the plugin idea was forming, I tried to be more active in the Eleventy Discord, chipping in on the support channel. Old tech-support reflexes came back, and so did an old frustrations. Community members run sixty-message threads to help an OP through. It\'s commendable. It\'s also exhausting. My recent coping move is to drop documentation links.\n\nBut the 11ty docs are hard to navigate if you don\'t know what you\'re looking for. Partly because Eleventy is so unopinionated about site structure that there\'s no canonical path through. And partly because the docs are a monolith that doesn\'t get fixed by an opportunistic pull request. They\'d need an active maintainer discussion to restructure.\n\nEleventy leaves its structural decisions open on purpose. That\'s its strength for experienced developers and its wall for everyone else. Baseline can be the thing that fills that gap: here\'s one good way to do it, here\'s why, and here\'s where to change it when you\'re ready.\n\nThe comparison isn\'t other Eleventy plugins. It\'s Nuxt, Astro, Hugo. Tools that shorten the distance between "installed" and "building."\n\n---\n\n## Where it\'s heading\n\nThe architecture keeps reshaping itself alongside the features: founding pieces get promoted to first-class layers, module boundaries get clearer, things get renamed. Each piece starts small and intentional, and evolves along what the project actually needs.\n\nOne other thing has nagged me for a while: Eleventy almost never gets named alongside Astro and Hugo, and Astro arrived later and overtook it almost immediately. The plugin doesn\'t fix that. But the hunch driving the work is that the gap isn\'t about capability. It\'s about that same distance, the one between "I\'ve installed it" and "I\'ve got a site running." Astro closes it out of the box. Baseline tries to close it for Eleventy.\n\nNext on the horizon: getting SEO right, and possibly a media management module.\n\n---\n\nIf any of this sounds useful, the docs are at [eleventy-baseline.dev](https://www.eleventy-baseline.dev/). The plugin is on npm as `@apleasantview/eleventy-plugin-baseline`. Releases roll continuously as `0.1.0-next.X`. Pin a version when you build something serious on top.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'about',
             permalink: '/about/',
             lang: 'en',
             layout: 'layouts/page.njk',
             title: 'About Eleventy Baseline',
             slug: 'about',
             description:
              'How a personal client-work starter became an opinionated infrastructure plugin for Eleventy.',
             date: 2026-05-23T00:00:00.000Z,
             translationKey: 'about',
             pageType: 'AboutPage',
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/en/pages/about.md',
             fileSlug: 'about',
             filePathStem: '/content/en/pages/about',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-23T00:00:00.000Z,
             rawInput:
              '\n_Baseline is an opinionated Eleventy plugin that handles the structural decisions you\'d otherwise wire up on every project. Looking for the marketing pitch? It\'s over on the [docs overview](https://www.eleventy-baseline.dev/docs/introduction/overview/)._\n\n_This page is the longer, more honest story._\n\n---\n\n## From starter to plugin\n\nBaseline started as my hundredth attempt at making a starter for client work, this time trying to be properly serious about it. The first version sat dormant for a while, but I kept coming back to it. It had one eye on the patterns and tooling already (silently) established in the Eleventy community.\n\nThe other eye was on what was missing for me: keeping client sites in sync without copying and rewriting files across projects, the per-language sitemaps I missed from Hugo, the single settings shape that WordPress gets right.\n\nThe shape clicked while I was thinking about something Zach Leatherman, Eleventy\'s creator, has said: that everything in Eleventy is essentially a plugin. I\'m paraphrasing, but that was the moment it stopped being a starter in my head.\n\nThe rewrite landed on the 1st of December 2025 as a single commit, "Rewrite baseline as a plugin." I announced the project on the Eleventy Discord shortly after, on the chance it might be useful to other people too.\n\nThat shift changed what the project needed to be. A personal starter can be implicit. You know why things are the way they are because you put them there. A plugin can\'t coast on that. Other people need to understand the choices, or at least trust them enough to get started.\n\nThe system has grown through use. Modules added when the project needed them, each with its own decisions, each leaning on the others. The starter became a system. Gradually, then all at once.\n\nThe framing shifted along with it. The earlier description called Baseline a "thin, optional wiring layer." That was true once. By April 2026 it had become an opinionated starting point. The value isn\'t that it\'s thin. The value is that these decisions are made, they work together, and the path to change one is clear when you disagree.\n\nWhat\'s in Baseline now is most of what I\'ve learned about building with Eleventy, and underneath that, fifteen years of working in tech, mostly but not only on the web. The decisions, the workarounds, the small conveniences that compound over hundreds of pages.\n\nIt evolved into its own thing along the way, but it grew out of an itch every Eleventy developer recognises: wiring up the same things on the third new project and wondering if there\'s a better way to keep that work.\n\nPutting the knowledge into code is the easier half. Finding the right shape for it, what to name, what to group, what belongs in the plugin and what belongs in the docs, is the harder one, and it\'s still in motion.\n\nToday Baseline is a working plugin handling structural decisions for an Eleventy project: things like responsive image widths, the head tags every site needs, per-language sitemaps with `x-default`, drafts kept out of production.\n\nIt ships continuously on npm as `0.1.0-next.X` and runs in production on its own docs site, on [a pleasant view](https://www.apleasantview.com), and on client sites. The code is stable. The architecture is settled. The words around it are still catching up.\n\n---\n\n## Eleventy and the educational gap\n\nAround the time the plugin idea was forming, I tried to be more active in the Eleventy Discord, chipping in on the support channel. Old tech-support reflexes came back, and so did an old frustrations. Community members run sixty-message threads to help an OP through. It\'s commendable. It\'s also exhausting. My recent coping move is to drop documentation links.\n\nBut the 11ty docs are hard to navigate if you don\'t know what you\'re looking for. Partly because Eleventy is so unopinionated about site structure that there\'s no canonical path through. And partly because the docs are a monolith that doesn\'t get fixed by an opportunistic pull request. They\'d need an active maintainer discussion to restructure.\n\nEleventy leaves its structural decisions open on purpose. That\'s its strength for experienced developers and its wall for everyone else. Baseline can be the thing that fills that gap: here\'s one good way to do it, here\'s why, and here\'s where to change it when you\'re ready.\n\nThe comparison isn\'t other Eleventy plugins. It\'s Nuxt, Astro, Hugo. Tools that shorten the distance between "installed" and "building."\n\n---\n\n## Where it\'s heading\n\nThe architecture keeps reshaping itself alongside the features: founding pieces get promoted to first-class layers, module boundaries get clearer, things get renamed. Each piece starts small and intentional, and evolves along what the project actually needs.\n\nOne other thing has nagged me for a while: Eleventy almost never gets named alongside Astro and Hugo, and Astro arrived later and overtook it almost immediately. The plugin doesn\'t fix that. But the hunch driving the work is that the gap isn\'t about capability. It\'s about that same distance, the one between "I\'ve installed it" and "I\'ve got a site running." Astro closes it out of the box. Baseline tries to close it for Eleventy.\n\nNext on the horizon: getting SEO right, and possibly a media management module.\n\n---\n\nIf any of this sounds useful, the docs are at [eleventy-baseline.dev](https://www.eleventy-baseline.dev/). The plugin is on npm as `@apleasantview/eleventy-plugin-baseline`. Releases roll continuously as `0.1.0-next.X`. Pin a version when you build something serious on top.\n',
             url: '/about/',
             outputPath: './dist/about/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: 'about',
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-05-23T00:00:00.000Z,
             dateModified: 2026-06-01T15:18:18.000Z },
          inputPath: './src/content/en/pages/about.md',
          fileSlug: 'about',
          filePathStem: '/content/en/pages/about',
          date: 2026-05-23T00:00:00.000Z,
          outputPath: './dist/about/index.html',
          url: '/about/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter],
          lang: 'en',
          locale: 'en',
          translationKey: 'about',
          isDefaultLang: true },
        { template:
           Template {
             inputPath: './src/content/en/pages/homepage.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: 'homepage',
             filePathStem: '/content/en/pages/homepage',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nEvery working Eleventy site rebuilds the same foundation: asset compilation, head tags, sitemap, image handling. The same groundwork every time.\n\nAnd every site hits the same limit. Your front matter is readable from anywhere. The rendered output is not.\n\nSo you end up writing the same workarounds: a backlinks index built from filenames, a table of contents re-parsed from Markdown, structured data hand-rolled per page.\n\nAll of it running parallel to the rendered output, drifting out of sync the moment anything is renamed.\n\nEleventy Baseline provides both, ready on day one. Already built, with a live reflection of everything you render. Your project still belongs to you.\n\n---\n\n## In practice\n\nBaseline is a working foundation for Eleventy sites.\n\nImages render at the right widths in modern formats, lazy by default. Links between pages live by name, so folder moves do not break them. The head tags fill from one settings file, with page-level overrides where needed.\n\nYour layouts, styles, scripts, and editorial structure stay yours. Keep the defaults where they help, and override where you need to.\n\n---\n\n## Built on Baseline\n\nThe site you are reading runs on Baseline. What you are looking at is the system itself in use, not an illustration of it.\n\nOpen any docs page and try it: the table of contents is built from the rendered HTML, the "Linked from" footer reads the content graph, the language switcher reads the settings, and the structured-data graph in the head is that same content graph, projected for search engines. All wired by the same system you are reading about.\n\nView source. Browse the repo. Run it locally. It\'s visible.\n\n---\n\n## The three-layer architecture\n\nResponsibilities stay separated, and each layer has one job. Changes stay predictable as the site grows.\n\n### State\n\nYour settings and options, normalised once at startup. Every module reads the same shape.\n\n### Runtime\n\nWhat the build knows about itself: the templates, the translations, the content graph. Modules read from here instead of from each other.\n\n### Modules\n\nThe features that read from both: assets, head, multilang, navigator, sitemap. None of them call each other; they read what they need from runtime.\n\nFull breakdown in the [[docs | docs]].\n\n---\n\n## Install and start\n\nInstall the packages, register Baseline in your Eleventy config, and run the dev server.\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img\nnpm install @apleasantview/eleventy-plugin-baseline\nnpm run dev\n```\n\nThe [[quickstart | quickstart]] walks through the full setup. The [[docs | docs]] cover the concept, modules and the architecture. The [[simple-baseline-site | simple site tutorial]] builds a small site from zero.\n\n### Rolling releases\n\nBaseline ships continuously. Each release advances the work, marked `0.1.0-next.X`. Pin a version when you build something serious on top.\n\nIf something in the docs claims a behaviour you cannot reproduce, the docs are probably wrong. Please [open an issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\nCommercial support available from [a pleasant view](https://www.apleasantview.com).\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: '/',
             lang: 'en',
             layout: 'layouts/page.njk',
             title: 'Eleventy Baseline',
             slug: 'home',
             description:
              'Eleventy Baseline is a plugin for Eleventy that provides a ready-made site foundation with assets, metadata, and a live content graph that keeps rendered output in sync.',
             date: 2026-05-17T00:00:00.000Z,
             translationKey: 'homepage',
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/en/pages/homepage.md',
             fileSlug: 'homepage',
             filePathStem: '/content/en/pages/homepage',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-17T00:00:00.000Z,
             rawInput:
              '\nEvery working Eleventy site rebuilds the same foundation: asset compilation, head tags, sitemap, image handling. The same groundwork every time.\n\nAnd every site hits the same limit. Your front matter is readable from anywhere. The rendered output is not.\n\nSo you end up writing the same workarounds: a backlinks index built from filenames, a table of contents re-parsed from Markdown, structured data hand-rolled per page.\n\nAll of it running parallel to the rendered output, drifting out of sync the moment anything is renamed.\n\nEleventy Baseline provides both, ready on day one. Already built, with a live reflection of everything you render. Your project still belongs to you.\n\n---\n\n## In practice\n\nBaseline is a working foundation for Eleventy sites.\n\nImages render at the right widths in modern formats, lazy by default. Links between pages live by name, so folder moves do not break them. The head tags fill from one settings file, with page-level overrides where needed.\n\nYour layouts, styles, scripts, and editorial structure stay yours. Keep the defaults where they help, and override where you need to.\n\n---\n\n## Built on Baseline\n\nThe site you are reading runs on Baseline. What you are looking at is the system itself in use, not an illustration of it.\n\nOpen any docs page and try it: the table of contents is built from the rendered HTML, the "Linked from" footer reads the content graph, the language switcher reads the settings, and the structured-data graph in the head is that same content graph, projected for search engines. All wired by the same system you are reading about.\n\nView source. Browse the repo. Run it locally. It\'s visible.\n\n---\n\n## The three-layer architecture\n\nResponsibilities stay separated, and each layer has one job. Changes stay predictable as the site grows.\n\n### State\n\nYour settings and options, normalised once at startup. Every module reads the same shape.\n\n### Runtime\n\nWhat the build knows about itself: the templates, the translations, the content graph. Modules read from here instead of from each other.\n\n### Modules\n\nThe features that read from both: assets, head, multilang, navigator, sitemap. None of them call each other; they read what they need from runtime.\n\nFull breakdown in the [[docs | docs]].\n\n---\n\n## Install and start\n\nInstall the packages, register Baseline in your Eleventy config, and run the dev server.\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img\nnpm install @apleasantview/eleventy-plugin-baseline\nnpm run dev\n```\n\nThe [[quickstart | quickstart]] walks through the full setup. The [[docs | docs]] cover the concept, modules and the architecture. The [[simple-baseline-site | simple site tutorial]] builds a small site from zero.\n\n### Rolling releases\n\nBaseline ships continuously. Each release advances the work, marked `0.1.0-next.X`. Pin a version when you build something serious on top.\n\nIf something in the docs claims a behaviour you cannot reproduce, the docs are probably wrong. Please [open an issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\nCommercial support available from [a pleasant view](https://www.apleasantview.com).\n',
             url: '/',
             outputPath: './dist/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: 'homepage',
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-05-17T00:00:00.000Z,
             dateModified: 2026-06-04T19:29:25.000Z },
          inputPath: './src/content/en/pages/homepage.md',
          fileSlug: 'homepage',
          filePathStem: '/content/en/pages/homepage',
          date: 2026-05-17T00:00:00.000Z,
          outputPath: './dist/index.html',
          url: '/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter],
          lang: 'en',
          locale: 'en',
          translationKey: 'homepage',
          isDefaultLang: true },
        { template:
           Template {
             inputPath: './src/content/fr/pages/homepage.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: 'homepage',
             filePathStem: '/content/fr/pages/homepage',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nChaque site Eleventy en production reconstruit la même fondation : compilation des assets, balises `head`, sitemap, gestion des images. Les mêmes fondations à refaire à chaque fois.\n\nEt chaque site se heurte à la même limite. Votre front matter est lisible depuis n\'importe où. La sortie rendue, non. Alors vous finissez par réécrire les mêmes contournements : un index de backlinks construit à partir des noms de fichiers, une table des matières reparsée depuis le Markdown, des données structurées rédigées à la main page par page. Tout cela tourne en parallèle de la sortie rendue, et se désynchronise dès qu\'on renomme quoi que ce soit.\n\nEleventy Baseline fournit les deux, prêts dès le premier jour. Déjà construits, avec un reflet vivant de tout ce que vous rendez. Votre projet reste le vôtre.\n\n---\n\n## En pratique\n\nBaseline est une fondation opérationnelle pour les sites Eleventy.\n\nLes images sont rendues aux bonnes largeurs dans des formats modernes, en lazy loading par défaut. Les liens entre pages vivent par leur nom : déplacer un dossier ne les casse pas. Les balises `head` se remplissent depuis un seul fichier de réglages, avec des surcharges au niveau de la page là où c\'est nécessaire.\n\nVos layouts, vos styles, vos scripts et votre structure éditoriale restent les vôtres. Gardez les valeurs par défaut là où elles aident, et surchargez là où vous en avez besoin.\n\n---\n\n## Construit sur Baseline\n\nLe site que vous lisez tourne sur Baseline. Ce que vous regardez, c\'est le système lui-même en usage, pas une illustration de celui-ci.\n\nOuvrez n\'importe quelle page de la documentation et essayez : la table des matières est construite à partir du HTML rendu, le pied de page "Linked from" lit le graphe de contenu, le sélecteur de langue lit les réglages, et le graphe de données structurées dans le `head` est ce même graphe de contenu, projeté pour les moteurs de recherche. Le tout câblé par le même système dont vous êtes en train de lire la description.\n\nRegardez le code source. Parcourez le dépôt. Lancez-le en local. Tout est visible.\n\n---\n\n## L\'architecture en trois couches\n\nLes responsabilités restent séparées, et chaque couche a une seule tâche. Les changements restent prévisibles à mesure que le site grandit.\n\n### State\n\nVos réglages et options, normalisés une fois au démarrage. Chaque module lit la même forme.\n\n### Runtime\n\nCe que le build sait de lui-même : les templates, les traductions, le graphe de contenu. Les modules lisent ici plutôt que les uns chez les autres.\n\n### Modules\n\nLes fonctionnalités qui lisent dans les deux : `assets`, `head`, `multilang`, `navigator`, `sitemap`. Aucun ne s\'appelle l\'un l\'autre ; chacun lit ce dont il a besoin dans le runtime.\n\nDétail complet dans la [[docs | documentation]].\n\n---\n\n## Installer et démarrer\n\nInstallez les paquets, enregistrez Baseline dans votre configuration Eleventy, et lancez le serveur de développement.\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img\nnpm install @apleasantview/eleventy-plugin-baseline\nnpm run dev\n```\n\nLe [[quickstart | guide de démarrage rapide]] détaille l\'installation complète. La [[docs | documentation]] couvre les modules et l\'architecture. Le [[simple-baseline-site | tutoriel simple-site]] construit un petit site à partir de zéro.\n\n### Versions glissantes\n\nBaseline est livré en continu. Chaque version fait avancer le travail, étiquetée `0.1.0-next.X`. Épinglez une version quand vous construisez quelque chose de sérieux par-dessus.\n\nSi la documentation décrit un comportement que vous n\'arrivez pas à reproduire, c\'est probablement la documentation qui a tort. Merci d\'[ouvrir une issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\nSupport commercial disponible auprès de [a pleasant view](https://www.apleasantview.com).\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: '/fr/',
             lang: 'fr',
             layout: 'layouts/page.njk',
             title: 'Eleventy Baseline',
             slug: 'home',
             description:
              "Eleventy Baseline est un plugin pour Eleventy qui fournit une fondation de site prête à l'emploi, avec les assets, les métadonnées et un graphe de contenu vivant qui maintient la sortie rendue synchronisée.",
             date: 2026-05-17T00:00:00.000Z,
             translationKey: 'homepage',
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/fr/pages/homepage.md',
             fileSlug: 'homepage',
             filePathStem: '/content/fr/pages/homepage',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-17T00:00:00.000Z,
             rawInput:
              '\nChaque site Eleventy en production reconstruit la même fondation : compilation des assets, balises `head`, sitemap, gestion des images. Les mêmes fondations à refaire à chaque fois.\n\nEt chaque site se heurte à la même limite. Votre front matter est lisible depuis n\'importe où. La sortie rendue, non. Alors vous finissez par réécrire les mêmes contournements : un index de backlinks construit à partir des noms de fichiers, une table des matières reparsée depuis le Markdown, des données structurées rédigées à la main page par page. Tout cela tourne en parallèle de la sortie rendue, et se désynchronise dès qu\'on renomme quoi que ce soit.\n\nEleventy Baseline fournit les deux, prêts dès le premier jour. Déjà construits, avec un reflet vivant de tout ce que vous rendez. Votre projet reste le vôtre.\n\n---\n\n## En pratique\n\nBaseline est une fondation opérationnelle pour les sites Eleventy.\n\nLes images sont rendues aux bonnes largeurs dans des formats modernes, en lazy loading par défaut. Les liens entre pages vivent par leur nom : déplacer un dossier ne les casse pas. Les balises `head` se remplissent depuis un seul fichier de réglages, avec des surcharges au niveau de la page là où c\'est nécessaire.\n\nVos layouts, vos styles, vos scripts et votre structure éditoriale restent les vôtres. Gardez les valeurs par défaut là où elles aident, et surchargez là où vous en avez besoin.\n\n---\n\n## Construit sur Baseline\n\nLe site que vous lisez tourne sur Baseline. Ce que vous regardez, c\'est le système lui-même en usage, pas une illustration de celui-ci.\n\nOuvrez n\'importe quelle page de la documentation et essayez : la table des matières est construite à partir du HTML rendu, le pied de page "Linked from" lit le graphe de contenu, le sélecteur de langue lit les réglages, et le graphe de données structurées dans le `head` est ce même graphe de contenu, projeté pour les moteurs de recherche. Le tout câblé par le même système dont vous êtes en train de lire la description.\n\nRegardez le code source. Parcourez le dépôt. Lancez-le en local. Tout est visible.\n\n---\n\n## L\'architecture en trois couches\n\nLes responsabilités restent séparées, et chaque couche a une seule tâche. Les changements restent prévisibles à mesure que le site grandit.\n\n### State\n\nVos réglages et options, normalisés une fois au démarrage. Chaque module lit la même forme.\n\n### Runtime\n\nCe que le build sait de lui-même : les templates, les traductions, le graphe de contenu. Les modules lisent ici plutôt que les uns chez les autres.\n\n### Modules\n\nLes fonctionnalités qui lisent dans les deux : `assets`, `head`, `multilang`, `navigator`, `sitemap`. Aucun ne s\'appelle l\'un l\'autre ; chacun lit ce dont il a besoin dans le runtime.\n\nDétail complet dans la [[docs | documentation]].\n\n---\n\n## Installer et démarrer\n\nInstallez les paquets, enregistrez Baseline dans votre configuration Eleventy, et lancez le serveur de développement.\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img\nnpm install @apleasantview/eleventy-plugin-baseline\nnpm run dev\n```\n\nLe [[quickstart | guide de démarrage rapide]] détaille l\'installation complète. La [[docs | documentation]] couvre les modules et l\'architecture. Le [[simple-baseline-site | tutoriel simple-site]] construit un petit site à partir de zéro.\n\n### Versions glissantes\n\nBaseline est livré en continu. Chaque version fait avancer le travail, étiquetée `0.1.0-next.X`. Épinglez une version quand vous construisez quelque chose de sérieux par-dessus.\n\nSi la documentation décrit un comportement que vous n\'arrivez pas à reproduire, c\'est probablement la documentation qui a tort. Merci d\'[ouvrir une issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\nSupport commercial disponible auprès de [a pleasant view](https://www.apleasantview.com).\n',
             url: '/fr/',
             outputPath: './dist/fr/index.html',
             lang: 'fr',
             locale: 'fr',
             translationKey: 'homepage',
             isDefaultLang: false,
             sitemap: [Object],
             datePublished: 2026-05-17T00:00:00.000Z,
             dateModified: 2026-06-04T19:29:25.000Z },
          inputPath: './src/content/fr/pages/homepage.md',
          fileSlug: 'homepage',
          filePathStem: '/content/fr/pages/homepage',
          date: 2026-05-17T00:00:00.000Z,
          outputPath: './dist/fr/index.html',
          url: '/fr/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter],
          lang: 'fr',
          locale: 'fr',
          translationKey: 'homepage',
          isDefaultLang: false },
        { template:
           Template {
             inputPath: './src/content/nl/pages/homepage.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: 'homepage',
             filePathStem: '/content/nl/pages/homepage',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nElke werkende Eleventy-site bouwt dezelfde basis opnieuw op: assets compileren, head-tags, sitemap, beeldverwerking. Steeds hetzelfde grondwerk.\n\nEn elke site loopt tegen dezelfde grens aan. Je front matter is overal leesbaar. De gerenderde output niet. Dus schrijf je telkens weer dezelfde omwegen: een backlinks-index op basis van bestandsnamen, een inhoudsopgave die opnieuw uit de Markdown wordt geparset, gestructureerde data per pagina met de hand opgesteld. Allemaal parallel aan de gerenderde output, die uit de pas loopt zodra er iets hernoemd wordt.\n\nEleventy Baseline biedt beide, klaar op dag één. Al gebouwd, met een levende weerspiegeling van alles wat je rendert. Je project blijft van jou.\n\n---\n\n## In de praktijk\n\nBaseline is een werkende basis voor Eleventy-sites.\n\nBeelden worden in de juiste breedtes en moderne formaten gerenderd, standaard lazy. Links tussen pagina\'s leven op naam, dus mappen verplaatsen breekt ze niet. De head-tags worden gevuld vanuit één settings-bestand, met overrides op paginaniveau waar nodig.\n\nJe layouts, stijlen, scripts en redactionele structuur blijven van jou. Houd de defaults waar ze helpen en override waar je het nodig hebt.\n\n---\n\n## Gebouwd op Baseline\n\nDe site die je nu leest draait op Baseline. Wat je voor je hebt is het systeem zelf in gebruik, geen illustratie ervan.\n\nOpen een willekeurige docs-pagina en probeer het: de inhoudsopgave wordt gebouwd uit de gerenderde HTML, de "Linked from"-footer leest de content graph, de taalwisselaar leest de settings, en de graph met gestructureerde data in de head is diezelfde content graph, geprojecteerd voor zoekmachines. Allemaal aangesloten op hetzelfde systeem waar je over leest.\n\nBekijk de broncode. Blader door de repo. Draai het lokaal. Het is zichtbaar.\n\n---\n\n## De drielagige architectuur\n\nVerantwoordelijkheden blijven gescheiden, en elke laag heeft één taak. Veranderingen blijven voorspelbaar terwijl de site groeit.\n\n### State\n\nJe settings en opties, eenmalig genormaliseerd bij het opstarten. Elke module leest dezelfde vorm.\n\n### Runtime\n\nWat de build over zichzelf weet: de templates, de vertalingen, de content graph. Modules lezen hieruit in plaats van uit elkaar.\n\n### Modules\n\nDe functies die uit beide lezen: `assets`, `head`, `multilang`, `navigator`, `sitemap`. Geen van hen roept de ander aan; ze lezen wat ze nodig hebben uit runtime.\n\nVolledige uitleg in de [[docs | docs]].\n\n---\n\n## Installeren en starten\n\nInstalleer de packages, registreer Baseline in je Eleventy-config en draai de dev-server.\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img\nnpm install @apleasantview/eleventy-plugin-baseline\nnpm run dev\n```\n\nDe [[quickstart | quickstart]] loopt de volledige setup door. De [[docs | docs]] behandelen de modules en de architectuur. De [[simple-baseline-site | tutorial voor een eenvoudige site]] bouwt een kleine site vanaf nul.\n\n### Doorlopende releases\n\nBaseline verschijnt continu. Elke release brengt het werk verder, gemarkeerd als `0.1.0-next.X`. Pin een versie als je er iets serieus bovenop bouwt.\n\nAls de docs een gedrag beweren dat je niet kunt reproduceren, dan kloppen de docs waarschijnlijk niet. [Open dan een issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\nCommerciële ondersteuning beschikbaar via [a pleasant view](https://www.apleasantview.com).\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'page',
             permalink: '/nl/',
             lang: 'nl',
             layout: 'layouts/page.njk',
             title: 'Eleventy Baseline',
             slug: 'home',
             description:
              'Eleventy Baseline is een plugin voor Eleventy die een kant-en-klare sitebasis biedt met assets, metadata en een levende content graph die de gerenderde output gesynchroniseerd houdt.',
             date: 2026-05-17T00:00:00.000Z,
             translationKey: 'homepage',
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/nl/pages/homepage.md',
             fileSlug: 'homepage',
             filePathStem: '/content/nl/pages/homepage',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-05-17T00:00:00.000Z,
             rawInput:
              '\nElke werkende Eleventy-site bouwt dezelfde basis opnieuw op: assets compileren, head-tags, sitemap, beeldverwerking. Steeds hetzelfde grondwerk.\n\nEn elke site loopt tegen dezelfde grens aan. Je front matter is overal leesbaar. De gerenderde output niet. Dus schrijf je telkens weer dezelfde omwegen: een backlinks-index op basis van bestandsnamen, een inhoudsopgave die opnieuw uit de Markdown wordt geparset, gestructureerde data per pagina met de hand opgesteld. Allemaal parallel aan de gerenderde output, die uit de pas loopt zodra er iets hernoemd wordt.\n\nEleventy Baseline biedt beide, klaar op dag één. Al gebouwd, met een levende weerspiegeling van alles wat je rendert. Je project blijft van jou.\n\n---\n\n## In de praktijk\n\nBaseline is een werkende basis voor Eleventy-sites.\n\nBeelden worden in de juiste breedtes en moderne formaten gerenderd, standaard lazy. Links tussen pagina\'s leven op naam, dus mappen verplaatsen breekt ze niet. De head-tags worden gevuld vanuit één settings-bestand, met overrides op paginaniveau waar nodig.\n\nJe layouts, stijlen, scripts en redactionele structuur blijven van jou. Houd de defaults waar ze helpen en override waar je het nodig hebt.\n\n---\n\n## Gebouwd op Baseline\n\nDe site die je nu leest draait op Baseline. Wat je voor je hebt is het systeem zelf in gebruik, geen illustratie ervan.\n\nOpen een willekeurige docs-pagina en probeer het: de inhoudsopgave wordt gebouwd uit de gerenderde HTML, de "Linked from"-footer leest de content graph, de taalwisselaar leest de settings, en de graph met gestructureerde data in de head is diezelfde content graph, geprojecteerd voor zoekmachines. Allemaal aangesloten op hetzelfde systeem waar je over leest.\n\nBekijk de broncode. Blader door de repo. Draai het lokaal. Het is zichtbaar.\n\n---\n\n## De drielagige architectuur\n\nVerantwoordelijkheden blijven gescheiden, en elke laag heeft één taak. Veranderingen blijven voorspelbaar terwijl de site groeit.\n\n### State\n\nJe settings en opties, eenmalig genormaliseerd bij het opstarten. Elke module leest dezelfde vorm.\n\n### Runtime\n\nWat de build over zichzelf weet: de templates, de vertalingen, de content graph. Modules lezen hieruit in plaats van uit elkaar.\n\n### Modules\n\nDe functies die uit beide lezen: `assets`, `head`, `multilang`, `navigator`, `sitemap`. Geen van hen roept de ander aan; ze lezen wat ze nodig hebben uit runtime.\n\nVolledige uitleg in de [[docs | docs]].\n\n---\n\n## Installeren en starten\n\nInstalleer de packages, registreer Baseline in je Eleventy-config en draai de dev-server.\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img\nnpm install @apleasantview/eleventy-plugin-baseline\nnpm run dev\n```\n\nDe [[quickstart | quickstart]] loopt de volledige setup door. De [[docs | docs]] behandelen de modules en de architectuur. De [[simple-baseline-site | tutorial voor een eenvoudige site]] bouwt een kleine site vanaf nul.\n\n### Doorlopende releases\n\nBaseline verschijnt continu. Elke release brengt het werk verder, gemarkeerd als `0.1.0-next.X`. Pin een versie als je er iets serieus bovenop bouwt.\n\nAls de docs een gedrag beweren dat je niet kunt reproduceren, dan kloppen de docs waarschijnlijk niet. [Open dan een issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues).\n\nCommerciële ondersteuning beschikbaar via [a pleasant view](https://www.apleasantview.com).\n',
             url: '/nl/',
             outputPath: './dist/nl/index.html',
             lang: 'nl',
             locale: 'nl',
             translationKey: 'homepage',
             isDefaultLang: false,
             sitemap: [Object],
             datePublished: 2026-05-17T00:00:00.000Z,
             dateModified: 2026-06-04T19:29:25.000Z },
          inputPath: './src/content/nl/pages/homepage.md',
          fileSlug: 'homepage',
          filePathStem: '/content/nl/pages/homepage',
          date: 2026-05-17T00:00:00.000Z,
          outputPath: './dist/nl/index.html',
          url: '/nl/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter],
          lang: 'nl',
          locale: 'nl',
          translationKey: 'homepage',
          isDefaultLang: false } ],
     all:
      [ { template:
           Template {
             inputPath: './src/content/docs/02.tutorial/00.index.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '00.index',
             filePathStem: '/content/docs/02.tutorial/00.index',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThese are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the [[feature-guide | feature guides]] chapter.\n\nNew to Baseline? The [[overview | overview]] covers what it is and who it is for.\n\n{% alertBlock "info" %}\n\nThe completed tutorial site (with how-to chapters) is [available on GitHub](https://github.com/apleasantview/simple-baseline-site). Please note that the repo might be stale.\n\n{% endalertBlock %}\n\n---\n\n## In this chapter\n\n{% include "partials/chapter-toc.njk" %}\n\nPrefer a checklist? See the [[quickstart | quickstart]].\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: '/docs/tutorial/',
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Tutorials',
             title: 'Tutorials',
             description:
              'Browse Baseline tutorials: build a simple site, the assets pipeline, the image shortcode, head and noindex, sitemaps and drafts, multilingual, deployment URL checks, and debugging with the navigator.',
             slug: 'tutorial',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/02.tutorial/00.index.md',
             fileSlug: '00.index',
             filePathStem: '/content/docs/02.tutorial/00.index',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nThese are end-to-end tutorials guiding you through a simple site and a multilingual site. Features are covered in the [[feature-guide | feature guides]] chapter.\n\nNew to Baseline? The [[overview | overview]] covers what it is and who it is for.\n\n{% alertBlock "info" %}\n\nThe completed tutorial site (with how-to chapters) is [available on GitHub](https://github.com/apleasantview/simple-baseline-site). Please note that the repo might be stale.\n\n{% endalertBlock %}\n\n---\n\n## In this chapter\n\n{% include "partials/chapter-toc.njk" %}\n\nPrefer a checklist? See the [[quickstart | quickstart]].\n',
             url: '/docs/tutorial/',
             outputPath: './dist/docs/tutorial/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-06-04T00:42:58.000Z },
          inputPath: './src/content/docs/02.tutorial/00.index.md',
          fileSlug: '00.index',
          filePathStem: '/content/docs/02.tutorial/00.index',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/tutorial/index.html',
          url: '/docs/tutorial/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/02.tutorial/01.simple-site.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '01.simple-site',
             filePathStem: '/content/docs/02.tutorial/01.simple-site',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nThe shortest path from an empty folder to a working Baseline site. By the end you\'ll have a single page rendering through Eleventy, a tiny stylesheet bundled automatically, and a sitemap that updates itself.\n\nThis is the tutorial every other tutorial builds on.\n\n---\n\n## What you will build\n\n- An Eleventy site with one page.\n- Baseline wired with default options: `multilingual` off, `sitemap` on, `navigator` on in dev and off in production.\n- A small stylesheet flowing through Baseline\'s assets pipeline, and an auto-generated `sitemap.xml` next to it.\n\n---\n\n## Prerequisites\n\n- Node 20.15.0 (or >=20).\n- npm.\n- A terminal.\n\n---\n\n## 1) Create the project\n\n```bash\nmkdir simple-baseline-site\ncd simple-baseline-site\nnpm init -y\n```\n\nOpen `package.json` and set `"type": "module"` (Baseline expects ESM):\n\n```json\n{\n\t"name": "simple-baseline-site",\n\t"type": "module",\n\t"scripts": {\n\t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n\t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n\t}\n}\n```\n\nThose two scripts are the only commands you need. From here on, `npm start` is local development and `npm run build` is the production build.\n\n---\n\n## 2) Install required packages\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img # Eleventy and 11ty Image\nnpm install rimraf cross-env # Helper packages\nnpm install @apleasantview/eleventy-plugin-baseline # Finally, install Baseline\n```\n\n---\n\n## 3) Configure Eleventy to use Baseline\n\nCreate `eleventy.config.js` in the project root:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(baseline(settings));\n}\n\nexport const config = baselineConfig;\n```\n\n---\n\nTwo things are worth a sentence:\n\n- `baseline(settings, options)` takes two arguments. `settings` is your site\'s identity (title, languages, head extras); `options` is runtime behaviour. Passing settings only leaves every option at its default, which is exactly what you want here.\n- `export const config = baselineConfig;` re-exports Baseline\'s directory contract, so Eleventy knows where to read input from and where to write output to. The [[config-export | config export reference]] explains why it has to be exported separately rather than set from inside the plugin.\n\n---\n\nBaseline wires Eleventy\'s `HtmlBasePlugin` to `process.env.URL` for you, which is what keeps canonical URLs and the sitemap pointing at the right origin.\n\nCreate a local `.env` for development, and set `URL` in your hosting environment for production. Baseline loads `dotenv` itself, so `process.env.URL` is available in both `_data/settings.js` and `eleventy.config.js`:\n\n```txt\nELEVENTY_ENV="development"\nURL="http://localhost:8080/"\n```\n\n---\n\n## 4) Required site data\n\nCreate `src/_data/settings.js`. This is the canonical home for everything that identifies the site: title, production URL, indexing preferences, and the head extras (the `<link>`, `<script>`, and `<meta>` tags Baseline injects into every page).\n\n```js\nexport default {\n\ttitle: \'Simple Baseline Site\',\n\ttagline: \'Hello, Eleventy + Baseline\',\n\turl: process.env.URL || \'http://localhost:8080/\',\n\tdefaultLanguage: \'en\',\n\tnoindex: false,\n\n\thead: {\n\t\tlink: [{ rel: \'stylesheet\', href: \'/assets/css/index.css\' }],\n\t\tscript: [{ src: \'/assets/js/index.js\', defer: true }],\n\t\tmeta: [{ name: \'color-scheme\', content: \'light dark\' }]\n\t}\n};\n```\n\nThe `head.link[]`, `head.script[]`, and `head.meta[]` arrays are how you add to the head from settings. Anything you put here lands on every page, alongside the defaults Baseline already produces (charset, viewport, title, description, canonical, robots).\n\nOne stylesheet link, one script tag, one colour-scheme hint is enough to get started.\n\n---\n\n## 5) Minimal layout\n\nCreate `src/_includes/layouts/base.njk`. Notice `<baseline-head></baseline-head>`: that is the placeholder. Baseline replaces it with a full `<head>` element at build time, so your layout never writes one of its own.\n\nIt sits as a sibling of `<body>`, not nested inside another head.\n\n{% raw %}\n\n```nunjucks\n<!DOCTYPE html>\n<html lang="{{ lang | default(settings.defaultLanguage) }}">\n  <baseline-head></baseline-head>\n  <body>\n    <main id="main">\n      <h1>{{ title }}</h1>\n      {{ content | safe }}\n      {% if page.url !== "/" %}\n        <p><a id="go-back" href=""><span style="vertical-align: text-bottom;">&#8592;</span>&nbsp;Go back</a></p>\n      {% endif %}\n    </main>\n    <script>\n    const backBtn = document.getElementById("go-back");\n    if ( backBtn ) {\n      backBtn.addEventListener("click", (event) => {\n        event.preventDefault();\n        history.back();\n      });\n    }\n    </script>\n  </body>\n</html>\n```\n\n{% endraw %}\n\n---\n\n## 6) Define your content directory\n\nEleventy uses directory data files to set repeating templating data, including permalinks for content files. We\'ll create one for our tutorial site. Inside `src`, create the content directory and its data file: `src/content/pages/pages.11tydata.js`.\n\nA convention in Baseline is to use the `slug` front matter field and generate permalinks from them. Setting the permalink field is reserved for the homepage ("/") and whenever control is warranted.\n\n```js\nexport default {\n\tlayout: \'layouts/base.njk\',\n\n\t// Ensure we have a value to work wih by explicitly asking for the slug field.\n\tpermalink: function ({ slug, page }) {\n\t\tif (!slug) {\n\t\t\tconsole.warn(`Warning: No slug found for ${page.inputPath}`);\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tconst normalizeSlug = this.slugify(slug);\n\t\t\treturn `/${normalizeSlug}/`;\n\t\t} catch (error) {\n\t\t\tconsole.error(`Error generating permalink for ${page.inputPath}:`, error);\n\t\t\treturn false;\n\t\t}\n\t}\n};\n```\n\n{% alertBlock %}\n\nIt would be tempting to use `eleventyCompute` for creating the permalink but this would always take precedence over the front matter field if set. The permalink function does plenty, including still allowing us to overwrite the field if needed.\n\n{% endalertBlock %}\n\n---\n\n## 7) Add a first page\n\nCreate `src/content/pages/index.md`:\n\n{% raw %}\n\n```md\n---\ntitle: \'Hello Baseline\'\nslug: \'simple-baseline-site\'\ndescription: \'A minimal Eleventy page powered by eleventy-plugin-baseline.\'\npermalink: \'/\'\nlayout: \'layouts/base.njk\'\n---\n\nYou are looking at a page rendered with Eleventy and the Baseline plugin defaults.\n\n## Index\n\n<ul class="index-links">\n{% for item in collections.all %}\n<li><a href="{{ item.url }}">{{ item.data.title }}</a></li>\n{% endfor %}\n</ul>\n```\n\n{% endraw %}\n\n---\n\n## 8) Minimal assets\n\nCreate `src/assets/assets.11tydata.js` to keep assets out of collections:\n\n```js\nexport default {\n\televentyExcludeFromCollections: true\n};\n```\n\nCreate `src/assets/css/index.css`:\n\n```css\nbody {\n\tfont-family: system-ui, sans-serif;\n\tmargin: 0;\n\tpadding: 2rem;\n\tline-height: 1.5;\n\tcolor: #1f2937;\n\tbackground: #f8fafc;\n}\n\nh1 {\n\tmargin-bottom: 0.5rem;\n}\n```\n\nCreate `src/assets/js/index.js`:\n\n```js\ndocument.addEventListener(\'DOMContentLoaded\', () => {\n\tconsole.log(\'Howdy!\');\n});\n```\n\n---\n\n## 9) Run the site locally\n\n```bash\nnpm start\n```\n\n- Open the printed local URL (default http://localhost:8080/). You should see the page title rendered as a heading.\n- While dev runs, Eleventy also writes to `dist/`, so you can peek at the generated files, including `sitemap.xml`.\n\n{% alertBlock "info" %}\n\nEleventy never cleans `dist/` for you. If a rebuild looks stale, stop the server and run `npm start` again.\n\n{% endalertBlock %}\n\n---\n\n## 10) Production build and inspect output\n\nChange `URL` in `.env` to an absolute URL. On a deployed site that\'s your real production URL; for this exercise, any absolute URL (e.g. `https://www.example.com/`) works to verify the output. Then run:\n\n```bash\nnpm run build\n```\n\n- Find the built files in `dist/`.\n- `dist/sitemap.xml` is generated automatically because the sitemap module is on by default.\n- Reset `URL` in `.env` to "http://localhost:8080/".\n\n---\n\n## Next steps\n\nIf you are looking to build a multilingual site, it\'s next up.\n\n- Add more pages under `src/content/pages/` with front matter (`title`, `description`, `permalink`, `layout`).\n- If you deploy under a subpath, set `pathPrefix` in `eleventy.config.js`.\n- Once you have a production URL, update `src/_data/settings.js` so canonical URLs and the sitemap match.\n- The natural next chapter is the [[assets-pipeline | assets pipeline tutorial]], which adds PostCSS and esbuild entries. After that, the [[head-and-noindex | head and noindex tutorial]] covers what Baseline injects into every page and how to extend it.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Tutorials',
             title: 'Build a simple site',
             description:
              'Create a single-language Eleventy site with Baseline defaults, head extras driven by settings, minimal CSS/JS, and an auto sitemap.',
             slug: 'simple-baseline-site',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/02.tutorial/01.simple-site.md',
             fileSlug: '01.simple-site',
             filePathStem: '/content/docs/02.tutorial/01.simple-site',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nThe shortest path from an empty folder to a working Baseline site. By the end you\'ll have a single page rendering through Eleventy, a tiny stylesheet bundled automatically, and a sitemap that updates itself.\n\nThis is the tutorial every other tutorial builds on.\n\n---\n\n## What you will build\n\n- An Eleventy site with one page.\n- Baseline wired with default options: `multilingual` off, `sitemap` on, `navigator` on in dev and off in production.\n- A small stylesheet flowing through Baseline\'s assets pipeline, and an auto-generated `sitemap.xml` next to it.\n\n---\n\n## Prerequisites\n\n- Node 20.15.0 (or >=20).\n- npm.\n- A terminal.\n\n---\n\n## 1) Create the project\n\n```bash\nmkdir simple-baseline-site\ncd simple-baseline-site\nnpm init -y\n```\n\nOpen `package.json` and set `"type": "module"` (Baseline expects ESM):\n\n```json\n{\n\t"name": "simple-baseline-site",\n\t"type": "module",\n\t"scripts": {\n\t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n\t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n\t}\n}\n```\n\nThose two scripts are the only commands you need. From here on, `npm start` is local development and `npm run build` is the production build.\n\n---\n\n## 2) Install required packages\n\n```bash\nnpm install @11ty/eleventy @11ty/eleventy-img # Eleventy and 11ty Image\nnpm install rimraf cross-env # Helper packages\nnpm install @apleasantview/eleventy-plugin-baseline # Finally, install Baseline\n```\n\n---\n\n## 3) Configure Eleventy to use Baseline\n\nCreate `eleventy.config.js` in the project root:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(baseline(settings));\n}\n\nexport const config = baselineConfig;\n```\n\n---\n\nTwo things are worth a sentence:\n\n- `baseline(settings, options)` takes two arguments. `settings` is your site\'s identity (title, languages, head extras); `options` is runtime behaviour. Passing settings only leaves every option at its default, which is exactly what you want here.\n- `export const config = baselineConfig;` re-exports Baseline\'s directory contract, so Eleventy knows where to read input from and where to write output to. The [[config-export | config export reference]] explains why it has to be exported separately rather than set from inside the plugin.\n\n---\n\nBaseline wires Eleventy\'s `HtmlBasePlugin` to `process.env.URL` for you, which is what keeps canonical URLs and the sitemap pointing at the right origin.\n\nCreate a local `.env` for development, and set `URL` in your hosting environment for production. Baseline loads `dotenv` itself, so `process.env.URL` is available in both `_data/settings.js` and `eleventy.config.js`:\n\n```txt\nELEVENTY_ENV="development"\nURL="http://localhost:8080/"\n```\n\n---\n\n## 4) Required site data\n\nCreate `src/_data/settings.js`. This is the canonical home for everything that identifies the site: title, production URL, indexing preferences, and the head extras (the `<link>`, `<script>`, and `<meta>` tags Baseline injects into every page).\n\n```js\nexport default {\n\ttitle: \'Simple Baseline Site\',\n\ttagline: \'Hello, Eleventy + Baseline\',\n\turl: process.env.URL || \'http://localhost:8080/\',\n\tdefaultLanguage: \'en\',\n\tnoindex: false,\n\n\thead: {\n\t\tlink: [{ rel: \'stylesheet\', href: \'/assets/css/index.css\' }],\n\t\tscript: [{ src: \'/assets/js/index.js\', defer: true }],\n\t\tmeta: [{ name: \'color-scheme\', content: \'light dark\' }]\n\t}\n};\n```\n\nThe `head.link[]`, `head.script[]`, and `head.meta[]` arrays are how you add to the head from settings. Anything you put here lands on every page, alongside the defaults Baseline already produces (charset, viewport, title, description, canonical, robots).\n\nOne stylesheet link, one script tag, one colour-scheme hint is enough to get started.\n\n---\n\n## 5) Minimal layout\n\nCreate `src/_includes/layouts/base.njk`. Notice `<baseline-head></baseline-head>`: that is the placeholder. Baseline replaces it with a full `<head>` element at build time, so your layout never writes one of its own.\n\nIt sits as a sibling of `<body>`, not nested inside another head.\n\n{% raw %}\n\n```nunjucks\n<!DOCTYPE html>\n<html lang="{{ lang | default(settings.defaultLanguage) }}">\n  <baseline-head></baseline-head>\n  <body>\n    <main id="main">\n      <h1>{{ title }}</h1>\n      {{ content | safe }}\n      {% if page.url !== "/" %}\n        <p><a id="go-back" href=""><span style="vertical-align: text-bottom;">&#8592;</span>&nbsp;Go back</a></p>\n      {% endif %}\n    </main>\n    <script>\n    const backBtn = document.getElementById("go-back");\n    if ( backBtn ) {\n      backBtn.addEventListener("click", (event) => {\n        event.preventDefault();\n        history.back();\n      });\n    }\n    </script>\n  </body>\n</html>\n```\n\n{% endraw %}\n\n---\n\n## 6) Define your content directory\n\nEleventy uses directory data files to set repeating templating data, including permalinks for content files. We\'ll create one for our tutorial site. Inside `src`, create the content directory and its data file: `src/content/pages/pages.11tydata.js`.\n\nA convention in Baseline is to use the `slug` front matter field and generate permalinks from them. Setting the permalink field is reserved for the homepage ("/") and whenever control is warranted.\n\n```js\nexport default {\n\tlayout: \'layouts/base.njk\',\n\n\t// Ensure we have a value to work wih by explicitly asking for the slug field.\n\tpermalink: function ({ slug, page }) {\n\t\tif (!slug) {\n\t\t\tconsole.warn(`Warning: No slug found for ${page.inputPath}`);\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tconst normalizeSlug = this.slugify(slug);\n\t\t\treturn `/${normalizeSlug}/`;\n\t\t} catch (error) {\n\t\t\tconsole.error(`Error generating permalink for ${page.inputPath}:`, error);\n\t\t\treturn false;\n\t\t}\n\t}\n};\n```\n\n{% alertBlock %}\n\nIt would be tempting to use `eleventyCompute` for creating the permalink but this would always take precedence over the front matter field if set. The permalink function does plenty, including still allowing us to overwrite the field if needed.\n\n{% endalertBlock %}\n\n---\n\n## 7) Add a first page\n\nCreate `src/content/pages/index.md`:\n\n{% raw %}\n\n```md\n---\ntitle: \'Hello Baseline\'\nslug: \'simple-baseline-site\'\ndescription: \'A minimal Eleventy page powered by eleventy-plugin-baseline.\'\npermalink: \'/\'\nlayout: \'layouts/base.njk\'\n---\n\nYou are looking at a page rendered with Eleventy and the Baseline plugin defaults.\n\n## Index\n\n<ul class="index-links">\n{% for item in collections.all %}\n<li><a href="{{ item.url }}">{{ item.data.title }}</a></li>\n{% endfor %}\n</ul>\n```\n\n{% endraw %}\n\n---\n\n## 8) Minimal assets\n\nCreate `src/assets/assets.11tydata.js` to keep assets out of collections:\n\n```js\nexport default {\n\televentyExcludeFromCollections: true\n};\n```\n\nCreate `src/assets/css/index.css`:\n\n```css\nbody {\n\tfont-family: system-ui, sans-serif;\n\tmargin: 0;\n\tpadding: 2rem;\n\tline-height: 1.5;\n\tcolor: #1f2937;\n\tbackground: #f8fafc;\n}\n\nh1 {\n\tmargin-bottom: 0.5rem;\n}\n```\n\nCreate `src/assets/js/index.js`:\n\n```js\ndocument.addEventListener(\'DOMContentLoaded\', () => {\n\tconsole.log(\'Howdy!\');\n});\n```\n\n---\n\n## 9) Run the site locally\n\n```bash\nnpm start\n```\n\n- Open the printed local URL (default http://localhost:8080/). You should see the page title rendered as a heading.\n- While dev runs, Eleventy also writes to `dist/`, so you can peek at the generated files, including `sitemap.xml`.\n\n{% alertBlock "info" %}\n\nEleventy never cleans `dist/` for you. If a rebuild looks stale, stop the server and run `npm start` again.\n\n{% endalertBlock %}\n\n---\n\n## 10) Production build and inspect output\n\nChange `URL` in `.env` to an absolute URL. On a deployed site that\'s your real production URL; for this exercise, any absolute URL (e.g. `https://www.example.com/`) works to verify the output. Then run:\n\n```bash\nnpm run build\n```\n\n- Find the built files in `dist/`.\n- `dist/sitemap.xml` is generated automatically because the sitemap module is on by default.\n- Reset `URL` in `.env` to "http://localhost:8080/".\n\n---\n\n## Next steps\n\nIf you are looking to build a multilingual site, it\'s next up.\n\n- Add more pages under `src/content/pages/` with front matter (`title`, `description`, `permalink`, `layout`).\n- If you deploy under a subpath, set `pathPrefix` in `eleventy.config.js`.\n- Once you have a production URL, update `src/_data/settings.js` so canonical URLs and the sitemap match.\n- The natural next chapter is the [[assets-pipeline | assets pipeline tutorial]], which adds PostCSS and esbuild entries. After that, the [[head-and-noindex | head and noindex tutorial]] covers what Baseline injects into every page and how to extend it.\n',
             url: '/docs/tutorial/simple-baseline-site/',
             outputPath: './dist/docs/tutorial/simple-baseline-site/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/02.tutorial/01.simple-site.md',
          fileSlug: '01.simple-site',
          filePathStem: '/content/docs/02.tutorial/01.simple-site',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/tutorial/simple-baseline-site/index.html',
          url: '/docs/tutorial/simple-baseline-site/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/03.feature-guide/04.sitemaps-and-drafts.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '04.sitemaps-and-drafts',
             filePathStem: '/content/docs/03.feature-guide/04.sitemaps-and-drafts',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nControl which pages end up in your sitemap, and let work-in-progress pages live alongside published ones without leaking into production. By the end you\'ll have per-page sitemap controls, a working `noindex` story, and a draft workflow that behaves differently in dev and build, the way you\'d want.\n\nTwo terms used below:\n\n- **Sitemap index.** The root `sitemap.xml` that lists per-language sitemaps when multilingual is on.\n- **Drafts preprocessor.** The build-time hook Baseline registers to drop `draft: true` pages from production builds (and only from production builds).\n\n---\n\n## What you will build\n\n- Pages that appear in `sitemap.xml`, and pages that don\'t.\n- Per-page sitemap controls: `ignore`, `changefreq`, `priority`, `lastmod`.\n- Draft pages that render in dev and quietly disappear in production.\n\n---\n\n## Prerequisites\n\n- Baseline installed and loaded (defaults keep the sitemap on).\n- Set `settings.url` to your production URL for correct sitemap and canonical links (use localhost while testing).\n- `package.json` with `"type": "module"` and the `dev`/`build` scripts:\n  ```json\n  {\n  \t"name": "simple-baseline-site",\n  \t"type": "module",\n  \t"scripts": {\n  \t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n  \t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n  \t}\n  }\n  ```\n\n---\n\n## 1) Ensure the sitemap module is on (default)\n\nSitemap is on by default, so the eleventy.config.js from the previous tutorial is enough - no new options needed:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\thead: {\n\t\t\t\ttitleSeparator: \' | \',\n\t\t\t\tshowGenerator: true\n\t\t\t}\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\n---\n\n## 2) Page with sitemap controls\n\nCreate `src/content/pages/sitemap-demo.md`:\n\n```md\n---\ntitle: \'Sitemap Demo\'\nslug: \'sitemap-demo\'\ndescription: \'Control sitemap entries.\'\nlayout: \'layouts/base.njk\'\nsitemap:\n  changefreq: \'weekly\'\n  priority: 0.7\n  lastmod: 2024-01-01\n---\n\nThis page stays in the sitemap with custom frequency, priority, and lastmod.\n```\n\n`changefreq`, `priority`, and `lastmod` are hints, not directives. Search engines treat them as suggestions, so adjust sparingly.\n\n---\n\n## 3) Noindex (site-wide and per-page)\n\nThree knobs, in widening order of scope:\n\n- Site-wide: set `noindex: true` in `_data/settings.js`. The whole sitemap is skipped.\n- Per-page: set `noindex: true` in front matter. The page renders a `robots` noindex tag and drops out of the sitemap.\n- Sitemap-only: use `sitemap: { ignore: true }` when the page should render normally but stay out of the sitemap.\n\n  ```yaml\n  sitemap:\n    ignore: true\n  eleventyExcludeFromCollections: true\n  ```\n\n  Two flags, two scopes worth distinguishing:\n  - `sitemap: { ignore: true }` removes the page from the sitemap; the page still renders.\n  - `eleventyExcludeFromCollections: true` keeps the page out of collections, and (because the sitemap reads from collections) out of the sitemap too.\n\n---\n\n## 4) Drafts\n\nAdd `draft: true` in front matter:\n\n```yaml\ndraft: true\n```\n\n- In dev (`npm start`): drafts render normally.\n- In build (`npm run build`, which sets `ELEVENTY_ENV=production`): drafts are skipped.\n- Baseline registers its own drafts preprocessor. If you already have one, yours wins; Baseline\'s is guarded against double-registration.\n\n---\n\n## 5) Run and inspect\n\n```bash\nnpm start\n```\n\n- Open pages normally.\n- Check `dist/sitemap.xml` while dev runs. It\'s emitted, drafts included.\n- Draft pages render in dev and show up in the dev sitemap. They drop out as soon as you build for production, since `npm run build` sets `ELEVENTY_ENV=production`.\n\n---\n\n## 6) Production build\n\nChange `URL` in `.env` to an absolute URL. On a deployed site that\'s your real production URL; for this exercise, any absolute URL (e.g. `https://www.example.com/`) works to verify the output. Then run:\n\n```bash\nnpm run build\n```\n\nThen inspect `dist/sitemap.xml`. A few things should be missing:\n\n- Pages with `sitemap.ignore: true`.\n- Every entry, if site-wide `noindex: true` is set.\n- Anything marked `draft: true`.\n- Reset `URL` in `.env` to "http://localhost:8080/".\n\n---\n\n## 7) Multilingual note\n\nWhen multilingual is on, Baseline emits a per-language sitemap (`/en/sitemap.xml`, `/nl/sitemap.xml`, and so on) plus a sitemap index at the root. The per-page `ignore`, `noindex`, and `draft` rules apply to each entry just the same.\n\n---\n\n## Next steps\n\n- Keep `settings.url` accurate in production, and set `pathPrefix` if you deploy under a subpath.\n- Use drafts freely for in-progress content. Just remember they reappear in dev.\n- Set defaults at the data layer: `_data/sitemap.js` for site-wide sitemap defaults, or directory data (e.g. `posts.11tydata.js`) to apply `sitemap` settings across a folder.\n- The [[sitemap | sitemap module reference]] has the full option list.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Feature guides',
             title: 'Sitemaps and Drafts',
             slug: 'sitemaps-and-drafts',
             description:
              'Control sitemap entries and drafts in Baseline: set per-page sitemap fields, apply noindex, and see how drafts behave in dev versus build.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/03.feature-guide/04.sitemaps-and-drafts.md',
             fileSlug: '04.sitemaps-and-drafts',
             filePathStem: '/content/docs/03.feature-guide/04.sitemaps-and-drafts',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nControl which pages end up in your sitemap, and let work-in-progress pages live alongside published ones without leaking into production. By the end you\'ll have per-page sitemap controls, a working `noindex` story, and a draft workflow that behaves differently in dev and build, the way you\'d want.\n\nTwo terms used below:\n\n- **Sitemap index.** The root `sitemap.xml` that lists per-language sitemaps when multilingual is on.\n- **Drafts preprocessor.** The build-time hook Baseline registers to drop `draft: true` pages from production builds (and only from production builds).\n\n---\n\n## What you will build\n\n- Pages that appear in `sitemap.xml`, and pages that don\'t.\n- Per-page sitemap controls: `ignore`, `changefreq`, `priority`, `lastmod`.\n- Draft pages that render in dev and quietly disappear in production.\n\n---\n\n## Prerequisites\n\n- Baseline installed and loaded (defaults keep the sitemap on).\n- Set `settings.url` to your production URL for correct sitemap and canonical links (use localhost while testing).\n- `package.json` with `"type": "module"` and the `dev`/`build` scripts:\n  ```json\n  {\n  \t"name": "simple-baseline-site",\n  \t"type": "module",\n  \t"scripts": {\n  \t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n  \t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n  \t}\n  }\n  ```\n\n---\n\n## 1) Ensure the sitemap module is on (default)\n\nSitemap is on by default, so the eleventy.config.js from the previous tutorial is enough - no new options needed:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\thead: {\n\t\t\t\ttitleSeparator: \' | \',\n\t\t\t\tshowGenerator: true\n\t\t\t}\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\n---\n\n## 2) Page with sitemap controls\n\nCreate `src/content/pages/sitemap-demo.md`:\n\n```md\n---\ntitle: \'Sitemap Demo\'\nslug: \'sitemap-demo\'\ndescription: \'Control sitemap entries.\'\nlayout: \'layouts/base.njk\'\nsitemap:\n  changefreq: \'weekly\'\n  priority: 0.7\n  lastmod: 2024-01-01\n---\n\nThis page stays in the sitemap with custom frequency, priority, and lastmod.\n```\n\n`changefreq`, `priority`, and `lastmod` are hints, not directives. Search engines treat them as suggestions, so adjust sparingly.\n\n---\n\n## 3) Noindex (site-wide and per-page)\n\nThree knobs, in widening order of scope:\n\n- Site-wide: set `noindex: true` in `_data/settings.js`. The whole sitemap is skipped.\n- Per-page: set `noindex: true` in front matter. The page renders a `robots` noindex tag and drops out of the sitemap.\n- Sitemap-only: use `sitemap: { ignore: true }` when the page should render normally but stay out of the sitemap.\n\n  ```yaml\n  sitemap:\n    ignore: true\n  eleventyExcludeFromCollections: true\n  ```\n\n  Two flags, two scopes worth distinguishing:\n  - `sitemap: { ignore: true }` removes the page from the sitemap; the page still renders.\n  - `eleventyExcludeFromCollections: true` keeps the page out of collections, and (because the sitemap reads from collections) out of the sitemap too.\n\n---\n\n## 4) Drafts\n\nAdd `draft: true` in front matter:\n\n```yaml\ndraft: true\n```\n\n- In dev (`npm start`): drafts render normally.\n- In build (`npm run build`, which sets `ELEVENTY_ENV=production`): drafts are skipped.\n- Baseline registers its own drafts preprocessor. If you already have one, yours wins; Baseline\'s is guarded against double-registration.\n\n---\n\n## 5) Run and inspect\n\n```bash\nnpm start\n```\n\n- Open pages normally.\n- Check `dist/sitemap.xml` while dev runs. It\'s emitted, drafts included.\n- Draft pages render in dev and show up in the dev sitemap. They drop out as soon as you build for production, since `npm run build` sets `ELEVENTY_ENV=production`.\n\n---\n\n## 6) Production build\n\nChange `URL` in `.env` to an absolute URL. On a deployed site that\'s your real production URL; for this exercise, any absolute URL (e.g. `https://www.example.com/`) works to verify the output. Then run:\n\n```bash\nnpm run build\n```\n\nThen inspect `dist/sitemap.xml`. A few things should be missing:\n\n- Pages with `sitemap.ignore: true`.\n- Every entry, if site-wide `noindex: true` is set.\n- Anything marked `draft: true`.\n- Reset `URL` in `.env` to "http://localhost:8080/".\n\n---\n\n## 7) Multilingual note\n\nWhen multilingual is on, Baseline emits a per-language sitemap (`/en/sitemap.xml`, `/nl/sitemap.xml`, and so on) plus a sitemap index at the root. The per-page `ignore`, `noindex`, and `draft` rules apply to each entry just the same.\n\n---\n\n## Next steps\n\n- Keep `settings.url` accurate in production, and set `pathPrefix` if you deploy under a subpath.\n- Use drafts freely for in-progress content. Just remember they reappear in dev.\n- Set defaults at the data layer: `_data/sitemap.js` for site-wide sitemap defaults, or directory data (e.g. `posts.11tydata.js`) to apply `sitemap` settings across a folder.\n- The [[sitemap | sitemap module reference]] has the full option list.\n',
             url: '/docs/feature-guide/sitemaps-and-drafts/',
             outputPath: './dist/docs/feature-guide/sitemaps-and-drafts/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/03.feature-guide/04.sitemaps-and-drafts.md',
          fileSlug: '04.sitemaps-and-drafts',
          filePathStem: '/content/docs/03.feature-guide/04.sitemaps-and-drafts',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/feature-guide/sitemaps-and-drafts/index.html',
          url: '/docs/feature-guide/sitemaps-and-drafts/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/03.feature-guide/05.deployment-url-checks.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '05.deployment-url-checks',
             filePathStem: '/content/docs/03.feature-guide/05.deployment-url-checks',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nKeep your URLs correct across dev, preview, and production, so canonicals, sitemap entries, and links never leak `localhost` to the live site. The mechanics are mostly Eleventy and environment variables; this chapter is the small set of habits that keep them honest.\n\nThree terms used below:\n\n- **Canonical.** The `<link rel="canonical">` URL Baseline writes into every page\'s head.\n- **pathPrefix.** Eleventy\'s option for deploying under a subpath (e.g. `/docs/`). Baseline\'s head and sitemap modules respect it.\n- **Preview build.** A non-production deploy (a Netlify deploy preview, for instance) where the origin differs from production.\n\n---\n\n## What you will build\n\n- A Baseline site that picks up the right origin for whichever environment it\'s in.\n- Canonical and sitemap URLs pointing at the expected domain, preview included.\n\n---\n\n## Prerequisites\n\n- Baseline installed and loaded.\n- `package.json` with `"type": "module"` and the `dev`/`build` scripts:\n  ```json\n  {\n  \t"name": "simple-baseline-site",\n  \t"type": "module",\n  \t"scripts": {\n  \t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n  \t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n  \t}\n  }\n  ```\n\n---\n\n## 1) Set settings.url (and, separately, pathPrefix)\n\nUse the `src/_data/settings.js` you already have from the previous tutorials. The field that matters for this chapter is `url`, the canonical origin:\n\n```js\nurl: process.env.URL || \'http://localhost:8080/\'; // override per env\n```\n\nIf you\'re deploying under a subpath, set `pathPrefix` in `eleventy.config.js` (e.g. `/my-site/`) – it lives on the Eleventy config, not in `settings`. Baseline\'s head and sitemap output respect it without further wiring.\n\n---\n\n## 2) Set environment URLs (local and CI)\n\n- Dev or local preview: create a local `.env` (don\'t commit it):\n  ```txt\n  ELEVENTY_ENV="development"\n  URL="http://localhost:8080/"\n  ```\n- Production: set `URL` to the live origin (e.g. `https://www.example.com`) in your hosting or CI environment.\n- Hosted previews (optional, e.g. Netlify): `URL` usually points to production while `DEPLOY_URL` and `DEPLOY_PRIME_URL` point to the preview. Baseline falls back to those when `URL` is missing. Skip if previews aren\'t part of your workflow.\n\nBaseline loads `dotenv` for you, so `process.env.URL` works in both `_data/settings.js` and `eleventy.config.js`. The `HtmlBasePlugin` and the sitemap module both read it (and `pathPrefix`, if set).\n\n---\n\n## 3) Run with the right URL per environment\n\nDev: confirm your `.env` is loaded (e.g. `URL="http://localhost:8080/"`), then:\n\n```bash\nnpm start\n```\n\nProduction: set `URL` in hosting or CI to the live origin (not an inline shell export), then:\n\n```bash\nnpm run build\n```\n\nSpot-check the rendered pages: canonical and sitemap entries should use the origin you expect.\n\n---\n\n## 4) Preview builds (optional)\n\n- On Netlify, `DEPLOY_URL` and `DEPLOY_PRIME_URL` provide the preview origin, while `URL` stays set to the live site for production builds. Other hosts differ; set an equivalent preview URL env var for whichever staging environment you have.\n- Confirm the rendered canonical and the sitemap root both match the preview domain.\n\n---\n\n## 5) Verify outputs\n\n- View source on a rendered page. The `<link rel="canonical">` and every absolute link in the head should use the right origin. If `URL` is set in CI or production, none of them should say `localhost`.\n- Inspect `dist/sitemap.xml` (and the per-language sitemaps if multilingual is on). URLs should start with the expected origin, plus `pathPrefix` if you\'ve set one.\n\n---\n\n## 6) PathPrefix checklist (if applicable)\n\nFor the full subpath setup, see [[deploy-under-a-subpath | Deploy Under a Subpath]].\n\n---\n\n## Next steps\n\n- Add a CI check that fails the build if `URL` is missing in production. One small step, lots of headaches saved.\n- Pair with the [[multilingual-baseline-site | multilingual site tutorial]] to confirm hreflang URLs use the correct origin once multilingual is on.\n- The [[config-export | config export reference]] covers `URL` and `pathPrefix` behaviour in full.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Feature guides',
             title: 'Deployment URL Checks',
             slug: 'deployment-url-checks',
             description:
              'Keep canonical, sitemap, and links pointing at the right origin across dev, preview, and production by setting URL and pathPrefix correctly and verifying the output.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/03.feature-guide/05.deployment-url-checks.md',
             fileSlug: '05.deployment-url-checks',
             filePathStem: '/content/docs/03.feature-guide/05.deployment-url-checks',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nKeep your URLs correct across dev, preview, and production, so canonicals, sitemap entries, and links never leak `localhost` to the live site. The mechanics are mostly Eleventy and environment variables; this chapter is the small set of habits that keep them honest.\n\nThree terms used below:\n\n- **Canonical.** The `<link rel="canonical">` URL Baseline writes into every page\'s head.\n- **pathPrefix.** Eleventy\'s option for deploying under a subpath (e.g. `/docs/`). Baseline\'s head and sitemap modules respect it.\n- **Preview build.** A non-production deploy (a Netlify deploy preview, for instance) where the origin differs from production.\n\n---\n\n## What you will build\n\n- A Baseline site that picks up the right origin for whichever environment it\'s in.\n- Canonical and sitemap URLs pointing at the expected domain, preview included.\n\n---\n\n## Prerequisites\n\n- Baseline installed and loaded.\n- `package.json` with `"type": "module"` and the `dev`/`build` scripts:\n  ```json\n  {\n  \t"name": "simple-baseline-site",\n  \t"type": "module",\n  \t"scripts": {\n  \t\t"start": "rimraf dist/ && npx @11ty/eleventy --serve",\n  \t\t"build": "rimraf dist/ && cross-env ELEVENTY_ENV=production npx @11ty/eleventy"\n  \t}\n  }\n  ```\n\n---\n\n## 1) Set settings.url (and, separately, pathPrefix)\n\nUse the `src/_data/settings.js` you already have from the previous tutorials. The field that matters for this chapter is `url`, the canonical origin:\n\n```js\nurl: process.env.URL || \'http://localhost:8080/\'; // override per env\n```\n\nIf you\'re deploying under a subpath, set `pathPrefix` in `eleventy.config.js` (e.g. `/my-site/`) – it lives on the Eleventy config, not in `settings`. Baseline\'s head and sitemap output respect it without further wiring.\n\n---\n\n## 2) Set environment URLs (local and CI)\n\n- Dev or local preview: create a local `.env` (don\'t commit it):\n  ```txt\n  ELEVENTY_ENV="development"\n  URL="http://localhost:8080/"\n  ```\n- Production: set `URL` to the live origin (e.g. `https://www.example.com`) in your hosting or CI environment.\n- Hosted previews (optional, e.g. Netlify): `URL` usually points to production while `DEPLOY_URL` and `DEPLOY_PRIME_URL` point to the preview. Baseline falls back to those when `URL` is missing. Skip if previews aren\'t part of your workflow.\n\nBaseline loads `dotenv` for you, so `process.env.URL` works in both `_data/settings.js` and `eleventy.config.js`. The `HtmlBasePlugin` and the sitemap module both read it (and `pathPrefix`, if set).\n\n---\n\n## 3) Run with the right URL per environment\n\nDev: confirm your `.env` is loaded (e.g. `URL="http://localhost:8080/"`), then:\n\n```bash\nnpm start\n```\n\nProduction: set `URL` in hosting or CI to the live origin (not an inline shell export), then:\n\n```bash\nnpm run build\n```\n\nSpot-check the rendered pages: canonical and sitemap entries should use the origin you expect.\n\n---\n\n## 4) Preview builds (optional)\n\n- On Netlify, `DEPLOY_URL` and `DEPLOY_PRIME_URL` provide the preview origin, while `URL` stays set to the live site for production builds. Other hosts differ; set an equivalent preview URL env var for whichever staging environment you have.\n- Confirm the rendered canonical and the sitemap root both match the preview domain.\n\n---\n\n## 5) Verify outputs\n\n- View source on a rendered page. The `<link rel="canonical">` and every absolute link in the head should use the right origin. If `URL` is set in CI or production, none of them should say `localhost`.\n- Inspect `dist/sitemap.xml` (and the per-language sitemaps if multilingual is on). URLs should start with the expected origin, plus `pathPrefix` if you\'ve set one.\n\n---\n\n## 6) PathPrefix checklist (if applicable)\n\nFor the full subpath setup, see [[deploy-under-a-subpath | Deploy Under a Subpath]].\n\n---\n\n## Next steps\n\n- Add a CI check that fails the build if `URL` is missing in production. One small step, lots of headaches saved.\n- Pair with the [[multilingual-baseline-site | multilingual site tutorial]] to confirm hreflang URLs use the correct origin once multilingual is on.\n- The [[config-export | config export reference]] covers `URL` and `pathPrefix` behaviour in full.\n',
             url: '/docs/feature-guide/deployment-url-checks/',
             outputPath: './dist/docs/feature-guide/deployment-url-checks/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-06-04T18:03:33.000Z },
          inputPath: './src/content/docs/03.feature-guide/05.deployment-url-checks.md',
          fileSlug: '05.deployment-url-checks',
          filePathStem: '/content/docs/03.feature-guide/05.deployment-url-checks',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/feature-guide/deployment-url-checks/index.html',
          url: '/docs/feature-guide/deployment-url-checks/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/04.how-to/00.index.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '00.index',
             filePathStem: '/content/docs/04.how-to/00.index',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nRecipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.\n\n---\n\n## Index\n\n{% include "partials/chapter-toc.njk" %}\n\nPrefer a guided start? See the [[simple-baseline-site | simple Baseline site]] tutorial.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: '/docs/how-to/',
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'How-To',
             title: "How-To's",
             slug: 'how-to',
             description:
              'Task-first recipes for things Baseline does not do for you, plus three guides on integrating Baseline into existing setups.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/04.how-to/00.index.md',
             fileSlug: '00.index',
             filePathStem: '/content/docs/04.how-to/00.index',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nRecipes for the things Baseline does not do for you, and a few guides on grafting it onto setups that already exist.\n\n---\n\n## Index\n\n{% include "partials/chapter-toc.njk" %}\n\nPrefer a guided start? See the [[simple-baseline-site | simple Baseline site]] tutorial.\n',
             url: '/docs/how-to/',
             outputPath: './dist/docs/how-to/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-06-04T00:42:58.000Z },
          inputPath: './src/content/docs/04.how-to/00.index.md',
          fileSlug: '00.index',
          filePathStem: '/content/docs/04.how-to/00.index',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/how-to/index.html',
          url: '/docs/how-to/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/04.how-to/01.customise-assets-pipeline.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '01.customise-assets-pipeline',
             filePathStem: '/content/docs/04.how-to/01.customise-assets-pipeline',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nWhen the fallback configs in the assets module are not enough, drop your own in. PostCSS for CSS, esbuild for JS. The module picks them up.\n\n---\n\n## Prerequisites\n\n- Baseline registered in `eleventy.config.js`.\n- Default entries in place: `src/assets/css/index.css` and `src/assets/js/index.js`.\n- `package.json` with `"type": "module"` and scripts (`start`, `build`).\n\n---\n\n## PostCSS config\n\nA `postcss.config.js` at the project root replaces Baseline\'s fallback wholesale. Bring the plugins you want, gate cssnano on production, and check the output.\n\n### 1) Install PostCSS and the plugins you plan to use:\n\n```bash\nnpm install postcss postcss-import postcss-preset-env cssnano postcss-mixins\n```\n\nOnce you ship your own `postcss.config.js`, the fallback plugins are gone. Whatever you list here has to be installed explicitly.\n\n---\n\n### 2) Add `postcss.config.js` at the project root:\n\n```js\nimport postcssImport from \'postcss-import\';\nimport postcssMixins from \'postcss-mixins\';\nimport postcssPresetEnv from \'postcss-preset-env\';\nimport cssnano from \'cssnano\';\n\nconst isProd = process.env.ELEVENTY_ENV === \'production\';\n\nconst plugins = [postcssImport(), postcssMixins(), postcssPresetEnv({ stage: 1 })];\n\nif (isProd) {\n\tplugins.push(cssnano({ preset: \'default\' }));\n}\n\n/** @type {import(\'postcss-load-config\').Config} */\nexport default {\n\tmap: isProd ? false : { inline: true },\n\tplugins\n};\n```\n\n---\n\n### 3) Exercise the config in your CSS (imports and mixins):\n\n`src/assets/css/base.css`:\n\n```css\n:root {\n\tcolor-scheme: light;\n}\n\nbody {\n\tfont-family: system-ui, sans-serif;\n\tmargin: 0;\n\tpadding: 2rem;\n\tline-height: 1.5;\n\tcolor: #1f2937;\n\tbackground: #f8fafc;\n}\n\nh1 {\n\tmargin-bottom: 0.5rem;\n}\n\n.pill {\n\tdisplay: inline-block;\n\tpadding: 0.25rem 0.75rem;\n\tborder-radius: 999px;\n\tbackground: #e0f2fe;\n\tcolor: #0f172a;\n\tfont-weight: 600;\n}\n```\n\n`src/assets/css/mixins.css`:\n\n```css\n@define-mixin linksMixin {\n\tcolor: #0f172a;\n\ttext-decoration: underline;\n\ttext-decoration-color: #fc35b9;\n\ttext-decoration-thickness: 2px;\n\ttext-underline-offset: 3px;\n\tfont-weight: 600;\n}\n```\n\n`src/assets/css/links.css`:\n\n```css\na {\n\t@mixin linksMixin;\n}\n\na:hover {\n\tcolor: #fc35b9;\n}\n```\n\n`src/assets/css/index.css`:\n\n```css\n@import \'./base.css\';\n@import \'./mixins.css\';\n@import \'./links.css\';\n```\n\n---\n\n### 4) Run and inspect.\n\n- Dev: `npx rimraf dist/ && npm run dev`\n- Build: `npx rimraf dist/ && npm run build`\n- Check `dist/assets/css/index.css`:\n  - Dev: expanded CSS with mapped imports; no minification.\n  - Prod: minified (cssnano), imports flattened, custom media resolved.\n\n### Notes\n\n- Your `postcss.config.js` fully overrides Baseline\'s fallback. Keep the entry file at `src/assets/css/index.css` and add partials via imports.\n- Reach for what you need (purge, RTL, lightningcss, others). Env guards are the cleanest way to keep dev output readable and production output optimised.\n\n---\n\n## Esbuild targets\n\nThe JS pipeline takes more nudging than the CSS one. You may want extra entry points, different targets, or a one-off inline bundle, and esbuild is the lever for all three.\n\n---\n\n### 1) Install and pin esbuild explicitly.\n\nBaseline depends on esbuild already, but esbuild\'s own docs recommend pinning the version you build against:\n\n```bash\nnpm install --save-exact --save-dev esbuild\n```\n\n---\n\n### 2) Add additional entry points.\n\nAn entry point is the file Baseline hands to esbuild as the start of a bundle. Each `index.js` under `src/assets/js/**/` is one entry point and produces one bundle in `dist/assets/js/`:\n\n```bash\nmkdir -p src/assets/js/home src/assets/js/about\necho "console.log(\'home bundle\');" > src/assets/js/home/index.js\necho "console.log(\'about bundle\');" > src/assets/js/about/index.js\n```\n\nReference them from a page\'s front matter:\n\n```md\n---\ntitle: \'Hello Baseline\'\ndescription: \'A minimal Eleventy page powered by eleventy-plugin-baseline.\'\npermalink: \'/\'\nlayout: \'layouts/base.njk\'\nhead:\n  script:\n    - src: \'/assets/js/home/index.js\'\n      defer: true\n---\n```\n\n---\n\n### 3) Inline a small script.\n\nFor tiny helpers, inline the bundled output with Baseline\'s `inlineESbuild` filter. `_baseline.paths.assets` is the resolved input path to your assets directory; concatenating the relative path keeps the example portable:\n\n{% raw %}\n\n```nunjucks\n{% set jsPath = _baseline.paths.assets ~ "js/about/index.js" %}\n{{ jsPath | inlineESbuild | safe }}\n```\n\n{% endraw %}\n\nThis bundles and minifies the file with esbuild\'s `es2020` target, then injects a `<script>...</script>` tag.\n\n---\n\n### 4) Set default target and minification for all bundles.\n\nPass `assets.esbuild` options when you register Baseline:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\tassets: {\n\t\t\t\tesbuild: {\n\t\t\t\t\tminify: process.env.ELEVENTY_ENV === \'production\',\n\t\t\t\t\ttarget: \'es2017\'\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\n---\n\n### 5) Override target or minification for a specific inline script.\n\nFor one-offs, pass options directly to the filter. They merge over your defaults from `assets.esbuild`:\n\n{% raw %}\n\n```nunjucks\n{% set jsPath = _baseline.paths.assets ~ "js/about/index.js" %}\n{{ jsPath | inlineESbuild({ minify: false, target: "es2018" }) | safe }}\n```\n\n{% endraw %}\n\n6. Verify.\n   - Dev: `npm start`\n   - Build: `npm run build`\n   - Check `dist/assets/js/**/index.js` for bundled output and size.\n   - For inlined scripts, view the page source and confirm the bundled code is present.\n\n---\n\n### Notes\n\n- Baseline\'s default JS bundling: any `index.js` under `src/assets/js/**/` is bundled, minified, and targeted to `es2020`.\n- Inline only for small helpers; keep larger bundles as external files so they cache.\n- A global override is yours to maintain. Revisit it whenever your browser support changes.\n- If you reach for the same inline overrides repeatedly, write your own filter that calls `inlineESbuild` with preset options and use that filter instead.\n\n---\n\n## See also\n\n- [[assets | Assets module]]\n- [[globals| Globals reference]]\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'How-To',
             title: 'Customise the Assets Pipeline',
             slug: 'customise-assets-pipeline',
             description:
              "Override Baseline's fallback PostCSS config, add esbuild entry points, and set targets and minification for the assets module.",
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/04.how-to/01.customise-assets-pipeline.md',
             fileSlug: '01.customise-assets-pipeline',
             filePathStem: '/content/docs/04.how-to/01.customise-assets-pipeline',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nWhen the fallback configs in the assets module are not enough, drop your own in. PostCSS for CSS, esbuild for JS. The module picks them up.\n\n---\n\n## Prerequisites\n\n- Baseline registered in `eleventy.config.js`.\n- Default entries in place: `src/assets/css/index.css` and `src/assets/js/index.js`.\n- `package.json` with `"type": "module"` and scripts (`start`, `build`).\n\n---\n\n## PostCSS config\n\nA `postcss.config.js` at the project root replaces Baseline\'s fallback wholesale. Bring the plugins you want, gate cssnano on production, and check the output.\n\n### 1) Install PostCSS and the plugins you plan to use:\n\n```bash\nnpm install postcss postcss-import postcss-preset-env cssnano postcss-mixins\n```\n\nOnce you ship your own `postcss.config.js`, the fallback plugins are gone. Whatever you list here has to be installed explicitly.\n\n---\n\n### 2) Add `postcss.config.js` at the project root:\n\n```js\nimport postcssImport from \'postcss-import\';\nimport postcssMixins from \'postcss-mixins\';\nimport postcssPresetEnv from \'postcss-preset-env\';\nimport cssnano from \'cssnano\';\n\nconst isProd = process.env.ELEVENTY_ENV === \'production\';\n\nconst plugins = [postcssImport(), postcssMixins(), postcssPresetEnv({ stage: 1 })];\n\nif (isProd) {\n\tplugins.push(cssnano({ preset: \'default\' }));\n}\n\n/** @type {import(\'postcss-load-config\').Config} */\nexport default {\n\tmap: isProd ? false : { inline: true },\n\tplugins\n};\n```\n\n---\n\n### 3) Exercise the config in your CSS (imports and mixins):\n\n`src/assets/css/base.css`:\n\n```css\n:root {\n\tcolor-scheme: light;\n}\n\nbody {\n\tfont-family: system-ui, sans-serif;\n\tmargin: 0;\n\tpadding: 2rem;\n\tline-height: 1.5;\n\tcolor: #1f2937;\n\tbackground: #f8fafc;\n}\n\nh1 {\n\tmargin-bottom: 0.5rem;\n}\n\n.pill {\n\tdisplay: inline-block;\n\tpadding: 0.25rem 0.75rem;\n\tborder-radius: 999px;\n\tbackground: #e0f2fe;\n\tcolor: #0f172a;\n\tfont-weight: 600;\n}\n```\n\n`src/assets/css/mixins.css`:\n\n```css\n@define-mixin linksMixin {\n\tcolor: #0f172a;\n\ttext-decoration: underline;\n\ttext-decoration-color: #fc35b9;\n\ttext-decoration-thickness: 2px;\n\ttext-underline-offset: 3px;\n\tfont-weight: 600;\n}\n```\n\n`src/assets/css/links.css`:\n\n```css\na {\n\t@mixin linksMixin;\n}\n\na:hover {\n\tcolor: #fc35b9;\n}\n```\n\n`src/assets/css/index.css`:\n\n```css\n@import \'./base.css\';\n@import \'./mixins.css\';\n@import \'./links.css\';\n```\n\n---\n\n### 4) Run and inspect.\n\n- Dev: `npx rimraf dist/ && npm run dev`\n- Build: `npx rimraf dist/ && npm run build`\n- Check `dist/assets/css/index.css`:\n  - Dev: expanded CSS with mapped imports; no minification.\n  - Prod: minified (cssnano), imports flattened, custom media resolved.\n\n### Notes\n\n- Your `postcss.config.js` fully overrides Baseline\'s fallback. Keep the entry file at `src/assets/css/index.css` and add partials via imports.\n- Reach for what you need (purge, RTL, lightningcss, others). Env guards are the cleanest way to keep dev output readable and production output optimised.\n\n---\n\n## Esbuild targets\n\nThe JS pipeline takes more nudging than the CSS one. You may want extra entry points, different targets, or a one-off inline bundle, and esbuild is the lever for all three.\n\n---\n\n### 1) Install and pin esbuild explicitly.\n\nBaseline depends on esbuild already, but esbuild\'s own docs recommend pinning the version you build against:\n\n```bash\nnpm install --save-exact --save-dev esbuild\n```\n\n---\n\n### 2) Add additional entry points.\n\nAn entry point is the file Baseline hands to esbuild as the start of a bundle. Each `index.js` under `src/assets/js/**/` is one entry point and produces one bundle in `dist/assets/js/`:\n\n```bash\nmkdir -p src/assets/js/home src/assets/js/about\necho "console.log(\'home bundle\');" > src/assets/js/home/index.js\necho "console.log(\'about bundle\');" > src/assets/js/about/index.js\n```\n\nReference them from a page\'s front matter:\n\n```md\n---\ntitle: \'Hello Baseline\'\ndescription: \'A minimal Eleventy page powered by eleventy-plugin-baseline.\'\npermalink: \'/\'\nlayout: \'layouts/base.njk\'\nhead:\n  script:\n    - src: \'/assets/js/home/index.js\'\n      defer: true\n---\n```\n\n---\n\n### 3) Inline a small script.\n\nFor tiny helpers, inline the bundled output with Baseline\'s `inlineESbuild` filter. `_baseline.paths.assets` is the resolved input path to your assets directory; concatenating the relative path keeps the example portable:\n\n{% raw %}\n\n```nunjucks\n{% set jsPath = _baseline.paths.assets ~ "js/about/index.js" %}\n{{ jsPath | inlineESbuild | safe }}\n```\n\n{% endraw %}\n\nThis bundles and minifies the file with esbuild\'s `es2020` target, then injects a `<script>...</script>` tag.\n\n---\n\n### 4) Set default target and minification for all bundles.\n\nPass `assets.esbuild` options when you register Baseline:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(\n\t\tbaseline(settings, {\n\t\t\tassets: {\n\t\t\t\tesbuild: {\n\t\t\t\t\tminify: process.env.ELEVENTY_ENV === \'production\',\n\t\t\t\t\ttarget: \'es2017\'\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t);\n}\n\nexport const config = baselineConfig;\n```\n\n---\n\n### 5) Override target or minification for a specific inline script.\n\nFor one-offs, pass options directly to the filter. They merge over your defaults from `assets.esbuild`:\n\n{% raw %}\n\n```nunjucks\n{% set jsPath = _baseline.paths.assets ~ "js/about/index.js" %}\n{{ jsPath | inlineESbuild({ minify: false, target: "es2018" }) | safe }}\n```\n\n{% endraw %}\n\n6. Verify.\n   - Dev: `npm start`\n   - Build: `npm run build`\n   - Check `dist/assets/js/**/index.js` for bundled output and size.\n   - For inlined scripts, view the page source and confirm the bundled code is present.\n\n---\n\n### Notes\n\n- Baseline\'s default JS bundling: any `index.js` under `src/assets/js/**/` is bundled, minified, and targeted to `es2020`.\n- Inline only for small helpers; keep larger bundles as external files so they cache.\n- A global override is yours to maintain. Revisit it whenever your browser support changes.\n- If you reach for the same inline overrides repeatedly, write your own filter that calls `inlineESbuild` with preset options and use that filter instead.\n\n---\n\n## See also\n\n- [[assets | Assets module]]\n- [[globals| Globals reference]]\n',
             url: '/docs/how-to/customise-assets-pipeline/',
             outputPath: './dist/docs/how-to/customise-assets-pipeline/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/04.how-to/01.customise-assets-pipeline.md',
          fileSlug: '01.customise-assets-pipeline',
          filePathStem: '/content/docs/04.how-to/01.customise-assets-pipeline',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/how-to/customise-assets-pipeline/index.html',
          url: '/docs/how-to/customise-assets-pipeline/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/04.how-to/02.deploy-under-subpath.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '02.deploy-under-subpath',
             filePathStem: '/content/docs/04.how-to/02.deploy-under-subpath',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nServe a Baseline site from a subpath like `/docs/` without breaking links, asset paths, canonical URLs, or the sitemap on the way.\n\n---\n\n## Prerequisites\n\n- Baseline registered in `eleventy.config.js`.\n- `package.json` with `"type": "module"` and scripts (`start`, `build`).\n- `settings.url` set to the production origin (no trailing slash, no subpath).\n- You deploy to a subpath (e.g. a GitHub Pages project site, a reverse proxy, or a Netlify subdirectory).\n\n---\n\n## 1) Set `pathPrefix` in Eleventy\'s config export.\n\nKeep `settings.url` pointed at the origin and put the subpath on `pathPrefix`:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(baseline(settings));\n}\n\nexport const config = {\n\t...baselineConfig,\n\tpathPrefix: \'/docs/\' // include leading and trailing slash\n};\n```\n\nEleventy rewrites root-relative URLs with `pathPrefix`, and Baseline\'s head and sitemap modules read it via Eleventy.\n\n---\n\n## 2) Keep `settings.url` clean (origin only).\n\nThe [[deployment-url-checks | Deployment URL Checks tutorial]] covers the env shape; canonicals and sitemap entries combine `settings.url` with `pathPrefix` automatically.\n\n---\n\n## 3) Use root-relative asset and page links.\n\nReference built assets and pages with leading slashes so Eleventy applies `pathPrefix`:\n\n{% raw %}\n\n```nunjucks\n<link rel="stylesheet" href="/assets/css/index.css">\n<script src="/assets/js/index.js" defer></script>\n<a href="/getting-started/">Getting started</a>\n```\n\n{% endraw %}\n\nAvoid hardcoded full URLs with the subpath baked in.\n\n---\n\n## 4) Build and inspect what comes out.\n\n- Dev: `npm start`\n- Build: `npm run build`\n- Open `dist/sitemap.xml` and confirm URLs include `/docs/`.\n- Inspect a built page for `<link rel="canonical">` and asset URLs that include `/docs/`.\n\n---\n\n## 5) Preview under the same subpath you\'ll deploy to.\n\n- Serve `dist/` from a subpath-capable server, or use Eleventy\'s preview with `--pathprefix="/docs/"` to spot broken links.\n- Click through pages and assets to confirm they resolve under `/docs/`.\n\n---\n\n## Notes\n\n- If you move back to root hosting, clear `pathPrefix` to avoid double paths.\n- Watch for hardcoded absolute URLs; prefer root-relative so Eleventy can rewrite with `pathPrefix`.\n\n---\n\n## Common pitfalls\n\n- Mixing the subpath into `settings.url` and also setting `pathPrefix` produces double `/docs/docs/` in links and the sitemap.\n- Hardcoded absolute URLs (e.g. `https://www.example.com/docs/...`) won\'t get rewritten; prefer root-relative.\n- Missing leading slashes on assets and links (`assets/js/index.js` instead of `/assets/js/index.js`) prevents `pathPrefix` from applying.\n- Building without `pathPrefix` and then deploying under a subpath breaks links. Build and preview with the same `pathPrefix` you plan to deploy under.\n\n---\n\n## See also\n\n- [[plugin-entrypoint | Plugin entrypoint reference]]\n- [[build-scripts-and-cleanup | Build scripts and cleanup]]\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'How-To',
             title: 'Deploy Under a Subpath',
             slug: 'deploy-under-a-subpath',
             description:
              'Serve your Baseline site from a subpath: set pathPrefix, keep settings.url clean, use root-relative links, and verify sitemap and canonical URLs.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/04.how-to/02.deploy-under-subpath.md',
             fileSlug: '02.deploy-under-subpath',
             filePathStem: '/content/docs/04.how-to/02.deploy-under-subpath',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nServe a Baseline site from a subpath like `/docs/` without breaking links, asset paths, canonical URLs, or the sitemap on the way.\n\n---\n\n## Prerequisites\n\n- Baseline registered in `eleventy.config.js`.\n- `package.json` with `"type": "module"` and scripts (`start`, `build`).\n- `settings.url` set to the production origin (no trailing slash, no subpath).\n- You deploy to a subpath (e.g. a GitHub Pages project site, a reverse proxy, or a Netlify subdirectory).\n\n---\n\n## 1) Set `pathPrefix` in Eleventy\'s config export.\n\nKeep `settings.url` pointed at the origin and put the subpath on `pathPrefix`:\n\n```js\nimport baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\nimport settings from \'./src/_data/settings.js\';\n\n/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */\nexport default async function (eleventyConfig) {\n\tawait eleventyConfig.addPlugin(baseline(settings));\n}\n\nexport const config = {\n\t...baselineConfig,\n\tpathPrefix: \'/docs/\' // include leading and trailing slash\n};\n```\n\nEleventy rewrites root-relative URLs with `pathPrefix`, and Baseline\'s head and sitemap modules read it via Eleventy.\n\n---\n\n## 2) Keep `settings.url` clean (origin only).\n\nThe [[deployment-url-checks | Deployment URL Checks tutorial]] covers the env shape; canonicals and sitemap entries combine `settings.url` with `pathPrefix` automatically.\n\n---\n\n## 3) Use root-relative asset and page links.\n\nReference built assets and pages with leading slashes so Eleventy applies `pathPrefix`:\n\n{% raw %}\n\n```nunjucks\n<link rel="stylesheet" href="/assets/css/index.css">\n<script src="/assets/js/index.js" defer></script>\n<a href="/getting-started/">Getting started</a>\n```\n\n{% endraw %}\n\nAvoid hardcoded full URLs with the subpath baked in.\n\n---\n\n## 4) Build and inspect what comes out.\n\n- Dev: `npm start`\n- Build: `npm run build`\n- Open `dist/sitemap.xml` and confirm URLs include `/docs/`.\n- Inspect a built page for `<link rel="canonical">` and asset URLs that include `/docs/`.\n\n---\n\n## 5) Preview under the same subpath you\'ll deploy to.\n\n- Serve `dist/` from a subpath-capable server, or use Eleventy\'s preview with `--pathprefix="/docs/"` to spot broken links.\n- Click through pages and assets to confirm they resolve under `/docs/`.\n\n---\n\n## Notes\n\n- If you move back to root hosting, clear `pathPrefix` to avoid double paths.\n- Watch for hardcoded absolute URLs; prefer root-relative so Eleventy can rewrite with `pathPrefix`.\n\n---\n\n## Common pitfalls\n\n- Mixing the subpath into `settings.url` and also setting `pathPrefix` produces double `/docs/docs/` in links and the sitemap.\n- Hardcoded absolute URLs (e.g. `https://www.example.com/docs/...`) won\'t get rewritten; prefer root-relative.\n- Missing leading slashes on assets and links (`assets/js/index.js` instead of `/assets/js/index.js`) prevents `pathPrefix` from applying.\n- Building without `pathPrefix` and then deploying under a subpath breaks links. Build and preview with the same `pathPrefix` you plan to deploy under.\n\n---\n\n## See also\n\n- [[plugin-entrypoint | Plugin entrypoint reference]]\n- [[build-scripts-and-cleanup | Build scripts and cleanup]]\n',
             url: '/docs/how-to/deploy-under-a-subpath/',
             outputPath: './dist/docs/how-to/deploy-under-a-subpath/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/04.how-to/02.deploy-under-subpath.md',
          fileSlug: '02.deploy-under-subpath',
          filePathStem: '/content/docs/04.how-to/02.deploy-under-subpath',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/how-to/deploy-under-a-subpath/index.html',
          url: '/docs/how-to/deploy-under-a-subpath/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/04.how-to/05.integrate-eleventy-base-blog.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '05.integrate-eleventy-base-blog',
             filePathStem: '/content/docs/04.how-to/05.integrate-eleventy-base-blog',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\n{% alertBlock "info" %}\n\nThis article is planned for revision, its content might be stale.\n\n{% endalertBlock %}\n\nAdd Baseline to the official `eleventy-base-blog` starter with as little disruption as the starter\'s existing wiring allows. The work splits into four pieces: bring Baseline in, line the starter\'s directories up with Baseline\'s contract, migrate the starter\'s hand-rolled `<head>` into Baseline\'s head pipeline, and confirm the output.\n\nIf you don\'t already have a project to integrate into, the [[simple-baseline-site | simple site tutorial]] is the lighter starting point.\n\n---\n\n## Prerequisites\n\n- You have `eleventy-base-blog` cloned and running (`npm install`, `npm run dev` works).\n- Eleventy 3.x; `package.json` has `dev` and `build` scripts.\n- `settings.url` will be set via env (`URL`) for production.\n\n---\n\n## 1) Install Baseline\n\n```bash\nnpm install @apleasantview/eleventy-plugin-baseline\n```\n\n---\n\n## 2) Wire Baseline into `eleventy.config.js`\n\nIn your existing config:\n\n{% stepsBlock "compact" %}\n\n- Remove the `HtmlBasePlugin` import and call. Baseline registers its own.\n\n- Import Baseline and the Baseline directory contract; add the plugin last so it sees the rest of your config:\n\n  ```js\n  import baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\n  import settings from \'./src/_data/settings.js\';\n\n  export default async function (eleventyConfig) {\n  \t// ...your existing config\n\n  \tawait eleventyConfig.addPlugin(baseline(settings));\n  }\n\n  export const config = baselineConfig; // spread to override if needed\n  ```\n\n- Update `passthroughCopy` inputs to `./src/static/` and `./src/content/feed/pretty-atom-feed.xsl`.\n\n- Remove watch targets for CSS or images if present (Baseline handles them).\n\n- Point CSS and JS bundle `toFileDirectory` to `assets/css` and `assets/js` respectively.\n\n- Set `base` to `process.env.URL`.\n\n{% endstepsBlock %}\n\nThe full file is in the [`eleventy-base-blog` fork](https://github.com/apleasantview/eleventy-baseline-blog/blob/baseline-edition/eleventy.config.js).\n\n---\n\n## 3) Add a local `.env` for development\n\n```txt\nELEVENTY_ENV="development"\nURL="http://localhost:8080"\n```\n\nIn CI and production, set `URL` to your live origin (e.g. `https://www.example.com`); Baseline uses it for canonical URLs and the sitemap.\n\n---\n\n## 4) Move Eleventy Base Blog folders under `src/`\n\nMove the following folders to match Baseline\'s defaults:\n\n- `_data` → `src/_data`\n- `_includes` → `src/_includes`\n- `content` → `src/content`\n- `css` → `src/assets/css`\n- `public` → `src/static`\n\nThe last move has an asymmetry worth knowing upfront. Baseline\'s directory contract sets `public: \'static\'`, so the virtual key on `eleventyConfig.directories` is `public` but the folder on disk stays `static/`. The [[config-export | config-export reference]] covers the same split.\n\nUpdate layouts and includes to resolve from `src/`, and content from `src/content/`. Delete `sitemap.xml.njk` in `src/content/`; Baseline\'s sitemap module handles it.\n\n---\n\n## 5) Add the required data file\n\n`src/_data/settings.js` is the single source for site identity and head extras. The starter\'s `_data/head.js` is no longer in play once Baseline is wired; head extras move onto `settings.head` instead (step 7 walks through the migration):\n\n```js\nexport default {\n\ttitle: \'Eleventy Base Blog (Baseline Edition)\',\n\ttagline: \'Baseline + Eleventy Base Blog\',\n\turl: process.env.URL || \'http://localhost:8080/\',\n\tdefaultLanguage: \'en\',\n\tnoindex: false,\n\n\thead: {\n\t\tlink: [{ rel: \'stylesheet\', href: \'/assets/css/index.css\' }],\n\t\tscript: [{ src: \'/assets/js/index.js\', defer: true }]\n\t}\n};\n```\n\n---\n\n## 6) Align assets\n\nMake sure these exist (or create minimal stubs):\n\n- `src/assets/css/index.css`: import your base CSS or start empty.\n- `src/assets/js/index.js`: optional JS entry; can be empty.\n- `src/assets/assets.11tydata.js` to keep the assets directory out of collections:\n  ```js\n  export default {\n  \televentyExcludeFromCollections: true\n  };\n  ```\n\n---\n\n## 7) Migrate the starter\'s head children\n\nThe starter\'s `base.njk` writes a `<head>` with three extras Baseline does not render for you: an Atom feed `<link>`, an inline `<style>` produced by `eleventy-plugin-bundle`, and a `@zachleat/heading-anchors` `<script type="module">`.\n\nWith Baseline, you do not author your own `<head>`; you push these into the head pipeline. One pattern per extra, in the same order:\n\n{% stepsBlock %}\n\n**Atom feed link → `settings.head.link[]`.** Site-wide static link. Add it to `src/_data/settings.js`:\n\n```js\nhead: {\n\tlink: [\n\t\t{ rel: \'stylesheet\', href: \'/assets/css/index.css\' },\n\t\t{\n\t\t\trel: \'alternate\',\n\t\t\ttype: \'application/atom+xml\',\n\t\t\ttitle: \'Eleventy Base Blog\',\n\t\t\thref: \'/feed/feed.xml\'\n\t\t}\n\t];\n}\n```\n\n<br>\n\n**`@zachleat/heading-anchors` script → `settings.head.script[]` plus an entry point.** Re-export the module from a small entry under `src/assets/js/heading-anchors/index.js`:\n\n```js\nimport \'@zachleat/heading-anchors\';\n```\n\nBaseline\'s assets pipeline bundles it to `dist/assets/js/heading-anchors/index.js`. Reference it in head extras:\n\n```js\nscript: [\n\t{ src: \'/assets/js/index.js\', defer: true },\n\t{ src: \'/assets/js/heading-anchors/index.js\', type: \'module\' }\n];\n```\n\n<br>\n\n**Per-page bundled CSS → `getBundle("css")` style block.** This is the non-trivial migration. The starter collects per-page CSS through `eleventy-plugin-bundle` and inlines the result. Baseline has no head-extras shape for inline `<style>`, so two approaches work depending on what the bundle is for:\n\n- **If the styles are page-specific and small**, keep the bundle plugin and inline them from the layout body (after `<baseline-head>`), with the small caveat that they sit outside the `<head>`. Most browsers handle this fine, but it\'s not strictly compliant.\n- **If the styles are reusable**, consolidate them into files under `src/assets/css/` and inline with Baseline\'s `inlinePostCSS` filter, called inside an inlineable head fragment that the layout includes:\n\n  {% raw %}\n\n  ```nunjucks\n  {% set cssPath = _baseline.paths.assets ~ "css/post.css" %}\n  {{ cssPath | inlinePostCSS | safe }}\n  ```\n\n  {% endraw %}\n\n  This belongs at the top of the layout body, not inside `<baseline-head>` (which Baseline replaces wholesale). The placeholder is your `<head>`; everything else goes in the body.\n\n{% endstepsBlock %}\n\n---\n\n## 8) Add `<baseline-head>` to `base.njk`\n\nThe placeholder sits inside `<html>`, as a sibling of `<body>`. Baseline replaces it with the rendered `<head>` element at build time. Don\'t author your own `<head>` around it:\n\n{% raw %}\n\n```nunjucks\n<!DOCTYPE html>\n<html lang="en">\n  <baseline-head></baseline-head>\n  <body>\n    ...\n  </body>\n</html>\n```\n\n{% endraw %}\n\n---\n\n## 9) Organise content and set permalinks.\n\nMove the following files to `src/content/pages/` and set their permalinks as needed:\n\n- `404.md`, `about.md`, `blog.njk`, `index.njk`, `tag-pages.njk`, `tags.njk`\n\nExample `index.njk`:\n\n{% raw %}\n\n```nunjucks\n---js\nconst permalink = "/";\n---\n```\n\n{% endraw %}\n\nAdd the permalink function in `blog.11tydata.js`:\n\n```js\nexport default {\n\t// Keep tags and layout keys.\n\tpermalink: function ({ page }) {\n\t\tif (page.inputPath.includes(\'11tydata.js\')) {\n\t\t\treturn false;\n\t\t}\n\t\treturn `/blog/${this.slugify(page.fileSlug)}/`;\n\t}\n};\n```\n\n---\n\n## 10) Use Baseline\'s inline-asset filters where it makes sense.\n\n    Replace direct CSS link-tags in `src/_includes/layouts/post.njk` and `src/_includes/layouts/home.njk` with the inline PostCSS filter. `_baseline.paths.assets` resolves to your assets input directory:\n\n    {% raw %}\n\n    ```nunjucks\n    {% set cssPath = _baseline.paths.assets ~ "css/message-box.css" %}\n    {{ cssPath | inlinePostCSS | safe }}\n    ```\n\n    {% endraw %}\n\n---\n\n## 11) Verify head, meta, and sitemap.\n\n    - Dev: `npx rimraf dist/ && npm run dev`\n    - Build: `npx rimraf dist/ && npm run build`\n    - Check a page\'s `<head>` for `<title>`, `<meta name="description">`, `<link rel="canonical">`, and (if multilingual) hreflang alternates.\n    - Inspect `dist/sitemap.xml` for correct URLs (uses `settings.url` and `pathPrefix` if set).\n\n---\n\n## 12) Optional: navigator and debug filters.\n\n    - Set `navigator: true` in the plugin options if you want the navigator page (dev only).\n    - Use the `_inspect`, `_json`, and `_keys` filters on a debug page to inspect data.\n\n---\n\n## Next steps\n\n- Add recommended build scripts and helper packages: [[build-scripts-and-cleanup | Build Scripts and Cleanup]].\n\n---\n\n## Notes\n\n- Keep `settings.url` origin-only; use `pathPrefix` if you deploy under a subpath.\n- Baseline\'s assets pipeline uses `src/assets/css/index.css` and `src/assets/js/index.js` as the default entry points.\n- If you have other CSS or JS paths, either point `settings.head.link[]` and `settings.head.script[]` at the Baseline output paths or mirror the files into `src/assets/`.\n\n---\n\n## See also\n\n- [[config-export | Config export reference]]\n- [[assets | Assets module]]\n- [[head | Head module]]\n- [[navigator | Navigator module]]\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'How-To',
             title: 'Integrate with Eleventy Base Blog',
             slug: 'integrate-eleventy-base-blog',
             description:
              'Add @apleasantview/eleventy-plugin-baseline to eleventy-base-blog: install, wire config, align data and assets, migrate head extras, and verify the build.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/04.how-to/05.integrate-eleventy-base-blog.md',
             fileSlug: '05.integrate-eleventy-base-blog',
             filePathStem: '/content/docs/04.how-to/05.integrate-eleventy-base-blog',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\n{% alertBlock "info" %}\n\nThis article is planned for revision, its content might be stale.\n\n{% endalertBlock %}\n\nAdd Baseline to the official `eleventy-base-blog` starter with as little disruption as the starter\'s existing wiring allows. The work splits into four pieces: bring Baseline in, line the starter\'s directories up with Baseline\'s contract, migrate the starter\'s hand-rolled `<head>` into Baseline\'s head pipeline, and confirm the output.\n\nIf you don\'t already have a project to integrate into, the [[simple-baseline-site | simple site tutorial]] is the lighter starting point.\n\n---\n\n## Prerequisites\n\n- You have `eleventy-base-blog` cloned and running (`npm install`, `npm run dev` works).\n- Eleventy 3.x; `package.json` has `dev` and `build` scripts.\n- `settings.url` will be set via env (`URL`) for production.\n\n---\n\n## 1) Install Baseline\n\n```bash\nnpm install @apleasantview/eleventy-plugin-baseline\n```\n\n---\n\n## 2) Wire Baseline into `eleventy.config.js`\n\nIn your existing config:\n\n{% stepsBlock "compact" %}\n\n- Remove the `HtmlBasePlugin` import and call. Baseline registers its own.\n\n- Import Baseline and the Baseline directory contract; add the plugin last so it sees the rest of your config:\n\n  ```js\n  import baseline, { config as baselineConfig } from \'@apleasantview/eleventy-plugin-baseline\';\n  import settings from \'./src/_data/settings.js\';\n\n  export default async function (eleventyConfig) {\n  \t// ...your existing config\n\n  \tawait eleventyConfig.addPlugin(baseline(settings));\n  }\n\n  export const config = baselineConfig; // spread to override if needed\n  ```\n\n- Update `passthroughCopy` inputs to `./src/static/` and `./src/content/feed/pretty-atom-feed.xsl`.\n\n- Remove watch targets for CSS or images if present (Baseline handles them).\n\n- Point CSS and JS bundle `toFileDirectory` to `assets/css` and `assets/js` respectively.\n\n- Set `base` to `process.env.URL`.\n\n{% endstepsBlock %}\n\nThe full file is in the [`eleventy-base-blog` fork](https://github.com/apleasantview/eleventy-baseline-blog/blob/baseline-edition/eleventy.config.js).\n\n---\n\n## 3) Add a local `.env` for development\n\n```txt\nELEVENTY_ENV="development"\nURL="http://localhost:8080"\n```\n\nIn CI and production, set `URL` to your live origin (e.g. `https://www.example.com`); Baseline uses it for canonical URLs and the sitemap.\n\n---\n\n## 4) Move Eleventy Base Blog folders under `src/`\n\nMove the following folders to match Baseline\'s defaults:\n\n- `_data` → `src/_data`\n- `_includes` → `src/_includes`\n- `content` → `src/content`\n- `css` → `src/assets/css`\n- `public` → `src/static`\n\nThe last move has an asymmetry worth knowing upfront. Baseline\'s directory contract sets `public: \'static\'`, so the virtual key on `eleventyConfig.directories` is `public` but the folder on disk stays `static/`. The [[config-export | config-export reference]] covers the same split.\n\nUpdate layouts and includes to resolve from `src/`, and content from `src/content/`. Delete `sitemap.xml.njk` in `src/content/`; Baseline\'s sitemap module handles it.\n\n---\n\n## 5) Add the required data file\n\n`src/_data/settings.js` is the single source for site identity and head extras. The starter\'s `_data/head.js` is no longer in play once Baseline is wired; head extras move onto `settings.head` instead (step 7 walks through the migration):\n\n```js\nexport default {\n\ttitle: \'Eleventy Base Blog (Baseline Edition)\',\n\ttagline: \'Baseline + Eleventy Base Blog\',\n\turl: process.env.URL || \'http://localhost:8080/\',\n\tdefaultLanguage: \'en\',\n\tnoindex: false,\n\n\thead: {\n\t\tlink: [{ rel: \'stylesheet\', href: \'/assets/css/index.css\' }],\n\t\tscript: [{ src: \'/assets/js/index.js\', defer: true }]\n\t}\n};\n```\n\n---\n\n## 6) Align assets\n\nMake sure these exist (or create minimal stubs):\n\n- `src/assets/css/index.css`: import your base CSS or start empty.\n- `src/assets/js/index.js`: optional JS entry; can be empty.\n- `src/assets/assets.11tydata.js` to keep the assets directory out of collections:\n  ```js\n  export default {\n  \televentyExcludeFromCollections: true\n  };\n  ```\n\n---\n\n## 7) Migrate the starter\'s head children\n\nThe starter\'s `base.njk` writes a `<head>` with three extras Baseline does not render for you: an Atom feed `<link>`, an inline `<style>` produced by `eleventy-plugin-bundle`, and a `@zachleat/heading-anchors` `<script type="module">`.\n\nWith Baseline, you do not author your own `<head>`; you push these into the head pipeline. One pattern per extra, in the same order:\n\n{% stepsBlock %}\n\n**Atom feed link → `settings.head.link[]`.** Site-wide static link. Add it to `src/_data/settings.js`:\n\n```js\nhead: {\n\tlink: [\n\t\t{ rel: \'stylesheet\', href: \'/assets/css/index.css\' },\n\t\t{\n\t\t\trel: \'alternate\',\n\t\t\ttype: \'application/atom+xml\',\n\t\t\ttitle: \'Eleventy Base Blog\',\n\t\t\thref: \'/feed/feed.xml\'\n\t\t}\n\t];\n}\n```\n\n<br>\n\n**`@zachleat/heading-anchors` script → `settings.head.script[]` plus an entry point.** Re-export the module from a small entry under `src/assets/js/heading-anchors/index.js`:\n\n```js\nimport \'@zachleat/heading-anchors\';\n```\n\nBaseline\'s assets pipeline bundles it to `dist/assets/js/heading-anchors/index.js`. Reference it in head extras:\n\n```js\nscript: [\n\t{ src: \'/assets/js/index.js\', defer: true },\n\t{ src: \'/assets/js/heading-anchors/index.js\', type: \'module\' }\n];\n```\n\n<br>\n\n**Per-page bundled CSS → `getBundle("css")` style block.** This is the non-trivial migration. The starter collects per-page CSS through `eleventy-plugin-bundle` and inlines the result. Baseline has no head-extras shape for inline `<style>`, so two approaches work depending on what the bundle is for:\n\n- **If the styles are page-specific and small**, keep the bundle plugin and inline them from the layout body (after `<baseline-head>`), with the small caveat that they sit outside the `<head>`. Most browsers handle this fine, but it\'s not strictly compliant.\n- **If the styles are reusable**, consolidate them into files under `src/assets/css/` and inline with Baseline\'s `inlinePostCSS` filter, called inside an inlineable head fragment that the layout includes:\n\n  {% raw %}\n\n  ```nunjucks\n  {% set cssPath = _baseline.paths.assets ~ "css/post.css" %}\n  {{ cssPath | inlinePostCSS | safe }}\n  ```\n\n  {% endraw %}\n\n  This belongs at the top of the layout body, not inside `<baseline-head>` (which Baseline replaces wholesale). The placeholder is your `<head>`; everything else goes in the body.\n\n{% endstepsBlock %}\n\n---\n\n## 8) Add `<baseline-head>` to `base.njk`\n\nThe placeholder sits inside `<html>`, as a sibling of `<body>`. Baseline replaces it with the rendered `<head>` element at build time. Don\'t author your own `<head>` around it:\n\n{% raw %}\n\n```nunjucks\n<!DOCTYPE html>\n<html lang="en">\n  <baseline-head></baseline-head>\n  <body>\n    ...\n  </body>\n</html>\n```\n\n{% endraw %}\n\n---\n\n## 9) Organise content and set permalinks.\n\nMove the following files to `src/content/pages/` and set their permalinks as needed:\n\n- `404.md`, `about.md`, `blog.njk`, `index.njk`, `tag-pages.njk`, `tags.njk`\n\nExample `index.njk`:\n\n{% raw %}\n\n```nunjucks\n---js\nconst permalink = "/";\n---\n```\n\n{% endraw %}\n\nAdd the permalink function in `blog.11tydata.js`:\n\n```js\nexport default {\n\t// Keep tags and layout keys.\n\tpermalink: function ({ page }) {\n\t\tif (page.inputPath.includes(\'11tydata.js\')) {\n\t\t\treturn false;\n\t\t}\n\t\treturn `/blog/${this.slugify(page.fileSlug)}/`;\n\t}\n};\n```\n\n---\n\n## 10) Use Baseline\'s inline-asset filters where it makes sense.\n\n    Replace direct CSS link-tags in `src/_includes/layouts/post.njk` and `src/_includes/layouts/home.njk` with the inline PostCSS filter. `_baseline.paths.assets` resolves to your assets input directory:\n\n    {% raw %}\n\n    ```nunjucks\n    {% set cssPath = _baseline.paths.assets ~ "css/message-box.css" %}\n    {{ cssPath | inlinePostCSS | safe }}\n    ```\n\n    {% endraw %}\n\n---\n\n## 11) Verify head, meta, and sitemap.\n\n    - Dev: `npx rimraf dist/ && npm run dev`\n    - Build: `npx rimraf dist/ && npm run build`\n    - Check a page\'s `<head>` for `<title>`, `<meta name="description">`, `<link rel="canonical">`, and (if multilingual) hreflang alternates.\n    - Inspect `dist/sitemap.xml` for correct URLs (uses `settings.url` and `pathPrefix` if set).\n\n---\n\n## 12) Optional: navigator and debug filters.\n\n    - Set `navigator: true` in the plugin options if you want the navigator page (dev only).\n    - Use the `_inspect`, `_json`, and `_keys` filters on a debug page to inspect data.\n\n---\n\n## Next steps\n\n- Add recommended build scripts and helper packages: [[build-scripts-and-cleanup | Build Scripts and Cleanup]].\n\n---\n\n## Notes\n\n- Keep `settings.url` origin-only; use `pathPrefix` if you deploy under a subpath.\n- Baseline\'s assets pipeline uses `src/assets/css/index.css` and `src/assets/js/index.js` as the default entry points.\n- If you have other CSS or JS paths, either point `settings.head.link[]` and `settings.head.script[]` at the Baseline output paths or mirror the files into `src/assets/`.\n\n---\n\n## See also\n\n- [[config-export | Config export reference]]\n- [[assets | Assets module]]\n- [[head | Head module]]\n- [[navigator | Navigator module]]\n',
             url: '/docs/how-to/integrate-eleventy-base-blog/',
             outputPath: './dist/docs/how-to/integrate-eleventy-base-blog/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-06-08T14:23:31.000Z },
          inputPath: './src/content/docs/04.how-to/05.integrate-eleventy-base-blog.md',
          fileSlug: '05.integrate-eleventy-base-blog',
          filePathStem: '/content/docs/04.how-to/05.integrate-eleventy-base-blog',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/how-to/integrate-eleventy-base-blog/index.html',
          url: '/docs/how-to/integrate-eleventy-base-blog/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/04.how-to/06.build-scripts-and-cleanup.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '06.build-scripts-and-cleanup',
             filePathStem: '/content/docs/04.how-to/06.build-scripts-and-cleanup',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           '\nA small set of npm scripts that take Baseline\'s dev and build commands from "works on my machine" to predictable across platforms. Three helpers do the work: `rimraf` for cleanup, `npm-run-all` for sequencing, and `cross-env` for portable env vars.\n\n---\n\n## Prerequisites\n\n- Baseline installed; `package.json` is ESM (`"type": "module"`).\n- `package.json` with `"type": "module"` and scripts (`start`, `build`).\n- Install dev dependencies: `npm install rimraf npm-run-all cross-env`.\n\n---\n\n## 1) Install helper packages:\n\n```bash\nnpm install rimraf npm-run-all cross-env\n```\n\n---\n\n## 2) Add scripts to `package.json`.\n\n```json\n{\n\t"scripts": {\n\t\t"start": "npm-run-all clean dev",\n\t\t"clean": "rimraf dist/",\n\t\t"dev": "npx @11ty/eleventy --serve",\n\t\t"build:eleventy": "cross-env ELEVENTY_ENV=production npx @11ty/eleventy",\n\t\t"build": "npm-run-all clean build:*",\n\t\t"dryrun": "npx @11ty/eleventy --dryrun"\n\t}\n}\n```\n\n---\n\n## 3) Run local dev with clean output:\n\n```bash\nnpm start\n```\n\nRuns `clean` (removes `dist/`), then the `dev` server.\n\n---\n\n## 4) Run a production build:\n\n```bash\nnpm run build\n```\n\nRuns `clean`, then `build:eleventy` with `ELEVENTY_ENV=production`.\n\n---\n\n## 5) Optional: dry run.\n\n```bash\nnpm run dryrun\n```\n\nInspect what would be built without writing files.\n\n---\n\n## 6) Gate `noindex` for preview deploys.\n\nPreview and staging environments should not show up in search results. Set a `PREVIEW` (or similar) env flag in those environments and read it from data or computed data to flip `noindex` on. The [[deployment-url-checks | deployment URL checks tutorial]] covers the full URL and env story alongside it.\n\n---\n\n## Notes\n\n- `rimraf dist/` keeps output clean across platforms; adjust the path if you change `dir.output`.\n- `npm-run-all` sequences clean → dev/build; keep `clean` first so stale artefacts don\'t leak into builds.\n- `cross-env` sets `ELEVENTY_ENV=production` portably.\n',
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: [Function: permalink],
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'How-To',
             title: 'Build Scripts and Cleanup',
             slug: 'build-scripts-and-cleanup',
             description:
              'Use npm-run-all, rimraf, and cross-env to keep Baseline builds clean and predictable for dev and production.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/04.how-to/06.build-scripts-and-cleanup.md',
             fileSlug: '06.build-scripts-and-cleanup',
             filePathStem: '/content/docs/04.how-to/06.build-scripts-and-cleanup',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              '\nA small set of npm scripts that take Baseline\'s dev and build commands from "works on my machine" to predictable across platforms. Three helpers do the work: `rimraf` for cleanup, `npm-run-all` for sequencing, and `cross-env` for portable env vars.\n\n---\n\n## Prerequisites\n\n- Baseline installed; `package.json` is ESM (`"type": "module"`).\n- `package.json` with `"type": "module"` and scripts (`start`, `build`).\n- Install dev dependencies: `npm install rimraf npm-run-all cross-env`.\n\n---\n\n## 1) Install helper packages:\n\n```bash\nnpm install rimraf npm-run-all cross-env\n```\n\n---\n\n## 2) Add scripts to `package.json`.\n\n```json\n{\n\t"scripts": {\n\t\t"start": "npm-run-all clean dev",\n\t\t"clean": "rimraf dist/",\n\t\t"dev": "npx @11ty/eleventy --serve",\n\t\t"build:eleventy": "cross-env ELEVENTY_ENV=production npx @11ty/eleventy",\n\t\t"build": "npm-run-all clean build:*",\n\t\t"dryrun": "npx @11ty/eleventy --dryrun"\n\t}\n}\n```\n\n---\n\n## 3) Run local dev with clean output:\n\n```bash\nnpm start\n```\n\nRuns `clean` (removes `dist/`), then the `dev` server.\n\n---\n\n## 4) Run a production build:\n\n```bash\nnpm run build\n```\n\nRuns `clean`, then `build:eleventy` with `ELEVENTY_ENV=production`.\n\n---\n\n## 5) Optional: dry run.\n\n```bash\nnpm run dryrun\n```\n\nInspect what would be built without writing files.\n\n---\n\n## 6) Gate `noindex` for preview deploys.\n\nPreview and staging environments should not show up in search results. Set a `PREVIEW` (or similar) env flag in those environments and read it from data or computed data to flip `noindex` on. The [[deployment-url-checks | deployment URL checks tutorial]] covers the full URL and env story alongside it.\n\n---\n\n## Notes\n\n- `rimraf dist/` keeps output clean across platforms; adjust the path if you change `dir.output`.\n- `npm-run-all` sequences clean → dev/build; keep `clean` first so stale artefacts don\'t leak into builds.\n- `cross-env` sets `ELEVENTY_ENV=production` portably.\n',
             url: '/docs/how-to/build-scripts-and-cleanup/',
             outputPath: './dist/docs/how-to/build-scripts-and-cleanup/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-05-18T00:18:19.000Z },
          inputPath: './src/content/docs/04.how-to/06.build-scripts-and-cleanup.md',
          fileSlug: '06.build-scripts-and-cleanup',
          filePathStem: '/content/docs/04.how-to/06.build-scripts-and-cleanup',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/how-to/build-scripts-and-cleanup/index.html',
          url: '/docs/how-to/build-scripts-and-cleanup/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        { template:
           Template {
             inputPath: './src/content/docs/05.core-reference/00.index.md',
             parsed: [Object],
             extraOutputSubdirectory: '',
             templateData: [TemplateData],
             fileSlug: [TemplateFileSlug],
             fileSlugStr: '00.index',
             filePathStem: '/content/docs/05.core-reference/00.index',
             linters: [],
             transforms: [Object],
             isVerbose: true,
             isDryRun: false,
             writeCount: 0,
             outputFormat: 'fs',
             behavior: [TemplateBehavior],
             renderCount: 0,
             _dataCache: [Promise],
             inputContent: [Promise],
             readingPromise: [Promise],
             _frontMatterDataCache: [Promise],
             computedData: [ComputedData],
             _usePermalinkRoot: undefined },
          rawInput:
           "\nThe inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.\n\nIf you are starting out, the [[introduction | introduction]] and [[tutorial | tutorials]] are friendlier doors. Reference assumes you know the surrounding piece and want the precise detail.\n\nThis chapter is grouped to mirror Baseline's two first layers and templating globals.\n\n---\n\n## State\n\nWhat you configure. The plugin call, the settings argument, and the directory contract Baseline ships.\n\n- [[plugin-entrypoint]]\n- [[site-settings]]\n- [[config-export]]\n\n---\n\n## Runtime\n\nWhat runs during the build, and what the modules read.\n\n- [[page-context]]\n- [[seo-graph]]\n- [[content-graph]]\n- [[internals]]\n\n---\n\n## Templating\n\nWhat you reach for from inside a template.\n\n- [[filters]]\n- [[globals]]\n- [[image-shortcode]]\n\n---\n\n[[docs | Back to docs]]\n",
          groupNumber: 0,
          data:
           { helpers: [Object],
             schema: [Object],
             settings: [Object],
             _baseline: [Object],
             _assets: {},
             _head: {},
             _multilang: {},
             _navigator: [Object],
             _sitemap: {},
             _snapshot: [Object],
             eleventyComputed: [Object],
             eleventy: [Object],
             pkg: [Object],
             type: 'article',
             permalink: '/docs/core-reference/',
             lang: 'en',
             layout: 'layouts/docs.njk',
             articleType: 'TechArticle',
             random: 'Random string',
             section: [Array],
             sectionLabel: 'Core reference',
             title: 'Core reference',
             slug: 'core-reference',
             description:
              'The inventory of what baseline gives you, grouped as state, runtime, and templating.',
             date: 2026-01-25T00:00:00.000Z,
             page: [Object],
             collections: [Circular *1],
             _pageContext: [Object],
             _seoGraph: [Object],
             _node: [Object],
             _backlinks: [Array],
             _outgoing: [Array],
             sitemap: [Object],
             head: [Object] },
          page:
           { inputPath: './src/content/docs/05.core-reference/00.index.md',
             fileSlug: '00.index',
             filePathStem: '/content/docs/05.core-reference/00.index',
             outputFileExtension: 'html',
             templateSyntax: 'njk,md',
             date: 2026-01-25T00:00:00.000Z,
             rawInput:
              "\nThe inventory of what Baseline gives you. Each page below is a lookup target: exact options, exact shapes, exact defaults.\n\nIf you are starting out, the [[introduction | introduction]] and [[tutorial | tutorials]] are friendlier doors. Reference assumes you know the surrounding piece and want the precise detail.\n\nThis chapter is grouped to mirror Baseline's two first layers and templating globals.\n\n---\n\n## State\n\nWhat you configure. The plugin call, the settings argument, and the directory contract Baseline ships.\n\n- [[plugin-entrypoint]]\n- [[site-settings]]\n- [[config-export]]\n\n---\n\n## Runtime\n\nWhat runs during the build, and what the modules read.\n\n- [[page-context]]\n- [[seo-graph]]\n- [[content-graph]]\n- [[internals]]\n\n---\n\n## Templating\n\nWhat you reach for from inside a template.\n\n- [[filters]]\n- [[globals]]\n- [[image-shortcode]]\n\n---\n\n[[docs | Back to docs]]\n",
             url: '/docs/core-reference/',
             outputPath: './dist/docs/core-reference/index.html',
             lang: 'en',
             locale: 'en',
             translationKey: undefined,
             isDefaultLang: true,
             sitemap: [Object],
             datePublished: 2026-01-25T00:00:00.000Z,
             dateModified: 2026-06-07T20:36:07.000Z },
          inputPath: './src/content/docs/05.core-reference/00.index.md',
          fileSlug: '00.index',
          filePathStem: '/content/docs/05.core-reference/00.index',
          date: 2026-01-25T00:00:00.000Z,
          outputPath: './dist/docs/core-reference/index.html',
          url: '/docs/core-reference/',
          templateContent: [Getter/Setter],
          content: [Getter/Setter] },
        ... 48 more items ] },
  _pageContext:
   { site:
      { title: 'Eleventy Baseline',
        tagline: 'Start building your site and skip the recurring setup work.',
        description: '',
        url: 'https://www.eleventy-baseline.dev',
        noindex: false },
     page:
      { inputPath: './src/navigator-core.html',
        fileSlug: 'navigator-core',
        filePathStem: '/navigator-core',
        outputFileExtension: 'html',
        templateSyntax: 'njk',
        date: 2026-06-08T15:47:32.302Z,
        url: '/navigator-core.html',
        outputPath: './dist/navigator-core.html',
        lang: 'en',
        locale: 'en',
        translationKey: undefined,
        isDefaultLang: true,
        sitemap: { ignore: false, changefreq: '', priority: -1 } },
     entry:
      { title: 'Navigator Core',
        description: 'Eleventy + Baseline internals',
        excerpt: undefined,
        slug: 'navigator-core',
        section: undefined,
        type: undefined,
        head: undefined,
        breadcrumbs: [] },
     query: { isHome: false },
     meta:
      { title: 'Navigator Core | Eleventy Baseline',
        description: 'Eleventy + Baseline internals',
        canonical: 'https://www.eleventy-baseline.dev/navigator-core.html',
        robots: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1',
        noindex: false },
     render: { generator: 'Eleventy v3.1.5' },
     head:
      { link:
         [ { rel: 'stylesheet',
             href: 'https://www.eleventy-baseline.dev/assets/css/index.css' },
           { rel: 'me', href: 'https://mastodon.social/@crisverstraeten' },
           { rel: 'icon',
             type: 'image/png',
             href: 'https://www.eleventy-baseline.dev/favicon-96x96.png',
             sizes: '96x96' },
           { rel: 'icon',
             type: 'image/svg+xml',
             href: 'https://www.eleventy-baseline.dev/favicon.svg' },
           { rel: 'shortcut icon', href: 'https://www.eleventy-baseline.dev/favicon.ico' },
           { rel: 'apple-touch-icon',
             href: 'https://www.eleventy-baseline.dev/apple-touch-icon.png' },
           { rel: 'manifest', href: 'https://www.eleventy-baseline.dev/site.webmanifest' } ],
        script:
         [ { src: '/assets/js/index.js', defer: true },
           { src: '/assets/js/vendor/index.js', defer: true } ],
        style: [],
        meta:
         [ { name: 'color-scheme', content: 'light dark' },
           { name: 'theme-color', content: '#ffffff' } ] } },
  _seoGraph:
   { url: 'https://www.eleventy-baseline.dev/navigator-core.html',
     schema:
      [ { '@type': 'WebSite',
          '@id': 'https://www.eleventy-baseline.dev/#/schema.org/WebSite',
          url: 'https://www.eleventy-baseline.dev',
          name: 'Eleventy Baseline',
          publisher:
           { '@id': 'https://www.eleventy-baseline.dev/#/schema.org/Organization/a-pleasant-view' },
          inLanguage: [ 'en', 'nl', 'fr' ] },
        { '@type': 'Organization',
          name: 'a pleasant view',
          url: 'https://www.apleasantview.com/',
          email: 'hello@apleasantview.com',
          taxID: '60532955',
          sameAs:
           [ 'https://mastodon.social/@crisverstraeten',
             'https://github.com/apleasantview',
             'https://www.linkedin.com/company/apleasantview' ],
          knowsAbout:
           [ 'Eleventy',
             'Static site generators',
             'Plugin architecture',
             'Web standards',
             'Open source software' ],
          '@id': 'https://www.eleventy-baseline.dev/#/schema.org/Organization/a-pleasant-view',
          logo: { '@id': 'https://www.eleventy-baseline.dev/#logo' },
          image: { '@id': 'https://www.eleventy-baseline.dev/#logo' } },
        { '@type': 'Person',
          name: 'Cristovao Verstraeten',
          givenName: 'Cristovao',
          familyName: 'Verstraeten',
          url: 'https://www.apleasantview.com/about/',
          jobTitle: 'Independent software developer',
          sameAs:
           [ 'https://mastodon.social/@crisverstraeten',
             'https://github.com/cristovaov',
             'https://www.linkedin.com/in/cristovaoverstraeten/' ],
          '@id': 'https://www.apleasantview.com/about/#/schema.org/Person' },
        { '@type': 'ImageObject',
          '@id': 'https://www.eleventy-baseline.dev/#logo',
          url: 'https://www.eleventy-baseline.dev/logo.png',
          contentUrl: 'https://www.eleventy-baseline.dev/logo.png',
          width: 400,
          height: 400 },
        { '@type': 'ImageObject',
          '@id': 'https://www.eleventy-baseline.dev/navigator-core.html#primaryimage',
          url: 'https://www.eleventy-baseline.dev/og.jpg',
          contentUrl: 'https://www.eleventy-baseline.dev/og.jpg',
          width: 1200,
          height: 630,
          caption: 'Eleventy Baseline' },
        { '@type': 'WebPage',
          '@id': 'https://www.eleventy-baseline.dev/navigator-core.html',
          url: 'https://www.eleventy-baseline.dev/navigator-core.html',
          name: 'Navigator Core',
          isPartOf: { '@id': 'https://www.eleventy-baseline.dev/#/schema.org/WebSite' },
          potentialAction: [ [Object] ],
          primaryImageOfPage: { '@id': 'https://www.eleventy-baseline.dev/navigator-core.html#primaryimage' },
          description: 'Eleventy + Baseline internals',
          inLanguage: 'en',
          datePublished: '2026-06-08T15:47:32.302Z',
          dateModified: '2026-06-08T15:47:32.302Z' } ],
     openGraph:
      { title: 'Navigator Core',
        type: 'website',
        url: 'https://www.eleventy-baseline.dev/navigator-core.html',
        locale: 'en',
        description: 'Eleventy + Baseline internals',
        siteName: 'Eleventy Baseline',
        image: 'https://www.eleventy-baseline.dev/og.jpg',
        imageAlt: 'Eleventy Baseline',
        imageWidth: 1200,
        imageHeight: 630 },
     twitter: { card: 'summary_large_image' } },
  _node:
   { title: 'Navigator Core',
     slug: 'navigator-core',
     description: 'Eleventy + Baseline internals',
     section: undefined,
     breadcrumbs: [],
     type: undefined,
     lang: 'en',
     locale: 'en',
     translationKey: undefined,
     isDefaultLang: true,
     date: 2026-06-08T15:47:30.605Z,
     url: '/navigator-core.html',
     excerpt: '← Go back',
     headings: [ { level: 2, text: 'Navigator', id: 'navigator' } ],
     sections: [],
     images: [] },
  _backlinks:
   [ { internal: true,
       from: '/docs/module/navigator/',
       to: '/navigator-core.html',
       text: 'in action',
       rel: [] },
     { internal: true,
       from: '/navigator-core.html',
       to: '/navigator-core.html',
       text: '← Go back',
       rel: [] } ],
  _outgoing:
   [ { internal: true,
       from: '/navigator-core.html',
       to: '/navigator-core.html',
       text: '← Go back',
       rel: [] } ] }
globals
{ range: [Function: range],
  cycler: [Function: cycler],
  joiner: [Function: joiner],
  date: { toUTCISO: [Function: toUTCISO] },
  _runtime: [Function: fn],
  _ctx: [Function: fn] }