Eleventy Plugin Baseline

A magic carpet ride

Table of Contents

Assets Pipeline Quickstart

Ship CSS and JS with Baseline’s built-in assets pipeline. You’ll add a CSS entry, a JS entry, run dev/build, and (optionally) inline assets in a template. Uses npm, Node 20.15.0+, and the same Baseline defaults as prior tutorials.

What you’ll build

  • A site that bundles src/assets/css/index.css via PostCSS (with Baseline’s fallback config if you don’t provide one).
  • A site that bundles src/assets/js/index.js via esbuild (bundled and minified).
  • Optional: inline CSS/JS in a template using Baseline filters.

Prerequisites

  • Node 20.15.0 (or >=20) and npm.
  • package.json with "type": "module" and scripts:
    {
    	"type": "module",
    	"scripts": {
    		"dev": "npx @11ty/eleventy --serve",
    		"build": "npx @11ty/eleventy"
    	}
    }
  • Baseline already installed and configured as in the simple tutorial (defaults on).

1) Ensure Baseline is loaded

eleventy.config.js should include:

import baseline, { config as baselineConfig } from '@apleasantview/eleventy-plugin-baseline';

/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
export default async function (eleventyConfig) {
	// Defaults enable assets-core, assets-postcss, assets-esbuild.
	eleventyConfig.addPlugin(baseline());
}

export const config = baselineConfig;

2) Add a page that links assets

Create src/content/pages/assets-quickstart.md:

---
title: 'Assets Quickstart'
description: 'CSS and JS bundled by Baseline.'
permalink: '/assets-quickstart/'
layout: 'layouts/base.njk'
---

CSS should style this page, and JS should log to the console. Here’s a small badge:

<span class="pill">Pending</span>

Your base layout should already include the head links from _data/head.js:

export default {
	link: [{ rel: 'stylesheet', href: '/assets/css/index.css' }],
	script: [{ src: '/assets/js/index.js', defer: true }]
};

3) Author the CSS entry

Create src/assets/css/index.css:

:root {
	color-scheme: light;
}

body {
	font-family: system-ui, sans-serif;
	margin: 0;
	padding: 2rem;
	line-height: 1.5;
	color: #1f2937;
	background: #f8fafc;
}

h1 {
	margin-bottom: 0.5rem;
}

.pill {
	display: inline-block;
	padding: 0.25rem 0.75rem;
	border-radius: 999px;
	background: #e0f2fe;
	color: #0f172a;
	font-weight: 600;
}

If you provide your own PostCSS config (e.g., postcss.config.js), Baseline will use it; otherwise it falls back to the built-in config.

4) Author the JS entry

Create src/assets/js/index.js:

document.addEventListener('DOMContentLoaded', () => {
	console.log('Baseline assets: JS is loaded');
	const pill = document.querySelector('.pill');
	if (pill) {
		pill.textContent = 'Bundled JS is running';
	}
});

5) Inline a small asset (optional)

Use the inline filters with a file path; they return the <style>/<script> wrappers for you:

{% set cssPath = _baseline.assets.input ~ "css/inline-example.css" %}
{{ cssPath | inlinePostCSS | safe }}

{% set jsPath  = _baseline.assets.input ~ "js/inline-example.js" %}
{{ jsPath  | inlineESbuild | safe }}
  • inlinePostCSS and inlineESbuild are async filters. Use | safe so the generated <style>/<script> isn’t escaped.
  • Both resolve configs/build from project root and return fallback comments on error (non-fatal).

6) Run the site locally

npx rimraf dist/ && npm run dev
  • Open the local URL (default http://localhost:8080/). Check that styles apply and the console logs appear.
  • While dev runs, Eleventy writes to dist/, so you can inspect dist/assets/css/index.css and dist/assets/js/index.js.
  • Changes to common asset formats (png/jpg/webp/gif/avif/svg) under src/assets trigger a rebuild during npm run dev.

Reminder: Eleventy doesn’t clean dist/; if you rerun dev/build, clear it first (e.g., npx rimraf dist).

7) Production build and inspect output

npx rimraf dist/ && npm run build
  • Check dist/assets/css/index.css (PostCSS output) and dist/assets/js/index.js (bundled/minified).

8) Next steps

  • Add your own postcss.config.js to customize plugins.
  • Add more entry points if needed (e.g., section-specific index.css under subfolders).
  • Use inlinePostCSS / inlineESbuild selectively for critical snippets. Avoid inlining large bundles.