Getting Started with 11ty Plugin
Complete setup guide for using Standard Framework with Eleventy.
Prerequisites
- Node.js 14+ installed
- Basic knowledge of 11ty
- Text editor
Installation
Step 1: Install 11ty and Standard Framework
npm init -y
npm install --save-dev @11ty/eleventy
npm install @zefish/standard
Step 2: Create eleventy.config.js
import Standard from "@zefish/standard";
export default function (eleventyConfig) {
// Add Standard Framework plugin
eleventyConfig.addPlugin(Standard);
return {
dir: {
input: "content",
output: "_site"
}
};
}
Step 3: Create Content Directory
mkdir content
echo "# Hello World" > content/index.md
Step 4: Create Base Layout
Create _includes/layouts/base.njk:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title or "My Site" }}</title>
{% standardAssets %}
</head>
<body class="bg-background text-foreground">
<header class="rhythm-block p-4">
<h1>Welcome</h1>
</header>
<main class="rhythm-block p-4">
{{ content | safe }}
</main>
<footer class="rhythm-block p-4">
<p>© 2024</p>
</footer>
</body>
</html>
Step 5: Build Your Site
npx @11ty/eleventy
Visit _site/index.html in your browser!
Project Structure
Organize your content logically:
my-site/
├── eleventy.config.js # 11ty configuration
├── package.json # Project metadata
├── content/
│ ├── index.md # Homepage
│ ├── about.md # About page
│ ├─ blog/
│ │ ├─ post-1.md
│ │ └─ post-2.md
│ └─ docs/
│ ├─ guide.md
│ └─ tutorial.md
├── _includes/
│ └── layouts/
│ ├── base.njk # Default layout
│ ├── article.njk # Article layout
│ └── blog-post.njk # Blog post layout
├── _site/ # Build output (auto-generated)
└── assets/
└── custom.css # Custom styles (optional)
Basic Page
Create content/about.md:
---
layout: layouts/base.njk
title: About Me
---
# About Me
Welcome to my website! This page demonstrates:
- **Beautiful typography** - Optimized for reading
- **Responsive design** - Works on all devices
- **Dark mode support** - Automatic theme switching
- **Semantic HTML** - Accessible and clean
The Standard Framework provides all the styling automatically.
Front Matter
Control page behavior with front matter:
---
layout: layouts/base.njk # Which layout to use
title: Page Title # Page title
description: Meta description # SEO meta description
tags: # Page tags
- important
- featured
eleventyNavigation: # Navigation menu
key: About
parent: Home
title: About
order: 1
---
Layouts
Create multiple layouts for different content types.
Article Layout
Create _includes/layouts/article.njk:
---
layout: layouts/base.njk
---
<article class="rhythm-block">
<h1>{{ title }}</h1>
<p class="text-lg text-foreground/80">{{ description }}</p>
<div class="mb-4">
{% if tags %}
{% for tag in tags %}
<span class="badge">{{ tag }}</span>
{% endfor %}
{% endif %}
</div>
<main class="prose max-w-prose">
{{ content | safe }}
</main>
</article>
Blog Post Layout
Create _includes/layouts/blog-post.njk:
---
layout: layouts/base.njk
---
<article class="rhythm-block">
<h1>{{ title }}</h1>
<div class="text-sm text-foreground/60">
Published: <time datetime="{{ date | dateFilter }}">
{{ date | dateFilter('long') }}
</time>
</div>
<hr class="my-4">
<main class="prose max-w-prose">
{{ content | safe }}
</main>
<hr class="my-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
{% if previousPost %}
<a href="{{ previousPost.url }}" class="btn btn-secondary">
← {{ previousPost.data.title }}
</a>
{% endif %}
{% if nextPost %}
<a href="{{ nextPost.url }}" class="btn btn-secondary">
{{ nextPost.data.title }} →
</a>
{% endif %}
</div>
</article>
Collections
Group related content.
Blog Posts Collection
Add to eleventy.config.js:
eleventyConfig.addCollection("blog", function (collection) {
return collection
.getFilteredByGlob("content/blog/**/*.md")
.sort((a, b) => b.date - a.date);
});
Use in template:
<h2>Recent Posts</h2>
<ul>
{% for post in collections.blog %}
<li>
<a href="{{ post.url }}">{{ post.data.title }}</a>
<time>{{ post.date | dateFilter }}</time>
</li>
{% endfor %}
</ul>
Filters
Add custom filters to transform data.
eleventyConfig.addFilter("uppercase", (value) => {
return value.toUpperCase();
});
eleventyConfig.addFilter("dateFilter", (date, format = "short") => {
return new Date(date).toLocaleDateString("en-US", {
year: "numeric",
month: format === "long" ? "long" : "2-digit",
day: "2-digit"
});
});
Use in templates:
{{ "hello" | uppercase }} <!-- HELLO -->
{{ date | dateFilter('long') }} <!-- January 21, 2025 -->
Includes
Reusable template snippets.
Create _includes/card.njk:
<div class="card p-4">
<h3>{{ title }}</h3>
<p>{{ description }}</p>
{% if link %}
<a href="{{ link }}" class="btn btn-primary btn-sm">Learn more</a>
{% endif %}
</div>
Use in templates:
{% include "card.njk" %}
{% include "card.njk", title="First", description="First card" %}
{% include "card.njk", title="Second", description="Second card" %}
Navigation
Create automatic navigation menu.
Add to eleventy.config.js:
import { EleventyHierarchyPlugin } from "@11ty/eleventy";
eleventyConfig.addPlugin(EleventyHierarchyPlugin);
Use in layout:
{% for entry in navigation %}
<a href="{{ entry.url }}"
{% if entry.url == page.url %}class="active"{% endif %}>
{{ entry.title }}
</a>
{% endfor %}
Passthrough Copy
Copy static files to output:
// Copy images
eleventyConfig.addPassthroughCopy("src/images/");
// Copy styles
eleventyConfig.addPassthroughCopy("src/css/");
// Copy custom JavaScript
eleventyConfig.addPassthroughCopy("src/js/");
Watch & Serve
Automatic rebuilding during development:
# Watch for changes and rebuild
npx @11ty/eleventy --serve
# Or configure in eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addWatchTarget("./content/**/*");
return {
dir: { input: "content" }
};
}
Build for Production
# Build optimized output
npx @11ty/eleventy
# Output goes to _site/
# Ready to deploy!
Package.json Scripts
Add helpful npm scripts:
{
"scripts": {
"start": "npx @11ty/eleventy --serve",
"build": "npx @11ty/eleventy",
"clean": "rm -rf _site"
}
}
Then use:
npm start # Start dev server
npm run build # Build for production
npm run clean # Remove output
Configuration Reference
Full eleventy.config.js Example
import Standard from "@zefish/standard";
export default function (eleventyConfig) {
// Add Standard Framework
eleventyConfig.addPlugin(Standard, {
outputDir: "assets/standard",
copyFiles: true,
useCDN: false
});
// Copy static files
eleventyConfig.addPassthroughCopy("src/images/");
eleventyConfig.addPassthroughCopy("src/styles/");
// Collections
eleventyConfig.addCollection("blog", (collection) => {
return collection
.getFilteredByGlob("content/blog/**/*.md")
.sort((a, b) => b.date - a.date);
});
// Filters
eleventyConfig.addFilter("head", (array, n) => {
if (!Array.isArray(array) || array.length === 0) {
return [];
}
if (n < 0) {
return array.slice(n);
}
return array.slice(0, n);
});
// Watch targets
eleventyConfig.addWatchTarget("./src/styles/");
return {
dir: {
input: "content",
output: "_site",
includes: "_includes"
},
templateFormats: ["md", "njk", "html"],
markdownTemplateEngine: "njk"
};
}
Troubleshooting
Templates Not Found
Make sure _includes is in your input directory or configured:
return {
dir: {
input: "content",
includes: "_includes" // relative to input
}
};
Styles Not Loading
Ensure {% standardAssets %} is in your base layout:
<head>
{% standardAssets %}
</head>
File Not Building
Check that the file:
- Is in the
contentdirectory - Has proper front matter
- Uses a supported format (.md,.njk,.html)
Changes Not Reflecting
When using npm start:
# Stop the server
Ctrl+C
# Restart
npm start
Next Steps
- CSS Framework – Style your content
- Markdown Features – Enhanced markdown
- Filters – Transform data
- Backlinks – Connect pages
Ready to build amazing sites? Let’s create some content! Learn Markdown