This skill should be used when scaffolding a Markdown-based documentation site using Eleventy. It generates a complete docs setup with base layout, data files, GitHub Pages deployment workflow, and passthrough copy configuration.
From soleurnpx claudepluginhub jikig-ai/soleur --plugin soleurThis skill uses the workspace's default tool permissions.
Scaffold a Markdown + Eleventy documentation site with build-time data injection and GitHub Pages deployment.
package.json in the project root (or willingness to create one)Ask the user:
https://example.com)Jean Deruelle)docs/)npm install --save-dev @11ty/eleventy
Add scripts to package.json:
{
"scripts": {
"docs:dev": "npx @11ty/eleventy --serve",
"docs:build": "npx @11ty/eleventy"
}
}
Ensure "type": "module" is set in package.json for ESM config.
Create eleventy.config.js at the project root:
const INPUT = "<docs-input-dir>";
export default function (eleventyConfig) {
eleventyConfig.addPassthroughCopy({ [`${INPUT}/css`]: "css" });
eleventyConfig.addPassthroughCopy({ [`${INPUT}/images`]: "images" });
// Add more passthrough copies as needed
}
export const config = {
dir: {
input: INPUT,
output: "_site",
includes: "_includes",
data: "_data",
},
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk",
templateFormats: ["md", "njk"],
};
Add _site/ to .gitignore.
<docs-input-dir>/
_data/
site.json # Site metadata (name, url, nav)
_includes/
base.njk # Base HTML layout
css/
style.css # Minimal starter CSS
images/ # Static images
index.njk # Landing page
pages/
getting-started.md # First content page
_data/site.json{
"name": "<Project Name>",
"url": "<site-url>",
"author": {
"name": "<Author Name>",
"url": "<site-url>"
},
"nav": [
{ "label": "Get Started", "url": "pages/getting-started.html" }
]
}
_includes/base.njkCreate a minimal HTML shell with:
site.nav{{ content | safe }}Use page.url comparison for aria-current="page" on nav links.
css/style.cssProvide a minimal starter stylesheet with CSS custom properties for easy theming.
Create .md files with YAML frontmatter:
---
title: Getting Started
description: "How to get started with <Project Name>"
layout: base.njk
permalink: pages/getting-started.html
---
If the project has components to catalog at build time, create data files in _data/:
// _data/version.js -- reads version from package.json
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
export default function () {
const pkg = JSON.parse(readFileSync(resolve("package.json"), "utf-8"));
return pkg.version;
}
Data files export a function that returns data available in all templates.
Create .github/workflows/deploy-docs.yml:
name: Deploy Documentation
on:
push:
branches: [main]
paths:
- '<docs-input-dir>/**'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
deploy:
environment:
name: github-pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx @11ty/eleventy
- uses: actions/configure-pages@v4
- uses: actions/upload-pages-artifact@v3
with:
path: _site
- uses: actions/deploy-pages@v4
npx @11ty/eleventy --serve
Open http://localhost:8080 and verify:
aria-current="page"{{ var }}) are NOT resolved inside YAML frontmatter. Use static strings for description in frontmatter, and template variables only in the page body.addPassthroughCopy() are relative to the project root, NOT the input directory. Use the mapping format: { "source/path": "output/path" }.export default) -- do not use CommonJS (module.exports).