docs-site
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.
docs-site Skill
Scaffold a Markdown + Eleventy documentation site with build-time data injection and GitHub Pages deployment.
Prerequisites
- Node.js 20+
- A
package.jsonin the project root (or willingness to create one)
Step 1: Gather Project Info
Ask the user:
- Project name -- Used in site title, footer, nav logo
- Site URL -- For meta tags, sitemap, og:url (e.g.,
https://example.com) - Author name -- For blog attribution, structured data, and E-E-A-T signals (e.g.,
Jean Deruelle) - Docs input directory -- Where docs source files live (e.g.,
docs/) - GitHub repository URL -- For nav link and deployment
- Pages to create -- Which pages beyond index (e.g., getting-started, changelog, API reference)
Step 2: Install Dependencies
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.
Step 3: Create Eleventy 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.
Step 4: Create Directory Structure
<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.njk
Create a minimal HTML shell with:
- Head: charset, viewport, description meta, title, CSS link
- Header: logo linking to index.html, nav from
site.nav - Main:
{{ content | safe }} - Footer: project name, links
Use page.url comparison for aria-current="page" on nav links.
css/style.css
Provide a minimal starter stylesheet with CSS custom properties for easy theming.
Content pages
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
---
Step 5: Data Files (Optional)
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.
Step 6: GitHub Pages Workflow
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
Step 7: Verify
npx @11ty/eleventy --serve
Open http://localhost:8080 and verify:
- All pages render correctly
- CSS loads
- Navigation works with
aria-current="page" - Data variables resolve in templates
Notes
- Nunjucks variables (
{{ var }}) are NOT resolved inside YAML frontmatter. Use static strings fordescriptionin frontmatter, and template variables only in the page body. - Passthrough copy paths in
addPassthroughCopy()are relative to the project root, NOT the input directory. Use the mapping format:{ "source/path": "output/path" }. - Eleventy v3 uses ESM (
export default) -- do not use CommonJS (module.exports).