xiaohongshu
xiaohongshu
eleventy
Build content-focused websites with Eleventy (11ty). Use when creating templates (.njk, .liquid), working with data cascade, collections, or deploying static sites.
Full skill instructions
Build fast, flexible static sites with Eleventy's zero-JS-by-default approach and powerful data cascade.
Eleventy perfectly matches progressive enhancement principles:
| Principle | Eleventy Implementation |
|---|---|
| HTML-first | Outputs pure static HTML |
| Zero JS by default | No JavaScript unless you add it |
| Template flexibility | Use any template language |
| Data-driven | Powerful data cascade system |
src/
├── _includes/ # Layouts and partials
│ ├── layouts/
│ │ └── base.njk
│ └── partials/
│ └── header.njk
├── _data/ # Global data files
│ ├── site.json # Site metadata
│ └── navigation.js # Dynamic data
├── content/ # Content pages
│ ├── index.njk # → /
│ ├── about.njk # → /about/
│ └── blog/
│ ├── blog.json # Directory data
│ └── post-1.md # → /blog/post-1/
├── assets/
│ ├── css/
│ └── js/
└── eleventy.config.js # Configuration
// eleventy.config.js
export default function(eleventyConfig) {
// Copy static assets
eleventyConfig.addPassthroughCopy('src/assets');
// Watch for changes
eleventyConfig.addWatchTarget('src/assets/css/');
// Add filters
eleventyConfig.addFilter('dateFormat', (date, format) => {
return new Intl.DateTimeFormat('en-US', {
dateStyle: format || 'medium'
}).format(date);
});
// Add shortcodes
eleventyConfig.addShortcode('year', () => `${new Date().getFullYear()}`);
// Add collections
eleventyConfig.addCollection('posts', (collectionApi) => {
return collectionApi
.getFilteredByGlob('src/content/blog/*.md')
.filter(post => !post.data.draft)
.sort((a, b) => b.date - a.date);
});
return {
dir: {
input: 'src',
output: '_site',
includes: '_includes',
data: '_data',
},
markdownTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
};
}
Data flows from global to specific, with later values overriding earlier:
1. Global Data (_data/*.json, _data/*.js)
2. Directory Data (blog/blog.json)
3. Template Front Matter
4. Computed Data
// src/_data/site.json
{
"title": "My Website",
"description": "A website built with Eleventy",
"url": "https://example.com",
"author": {
"name": "Your Name",
"email": "[email protected]"
}
}
// src/_data/navigation.js
export default [
{ text: 'Home', url: '/' },
{ text: 'About', url: '/about/' },
{ text: 'Blog', url: '/blog/' },
];
Apply data to all files in a directory:
// src/content/blog/blog.json
{
"layout": "layouts/post.njk",
"tags": ["posts"],
"permalink": "/blog/{{ page.fileSlug }}/"
}
---
title: My Blog Post
description: A description of this post
date: 2024-01-15
tags:
- javascript
- tutorial
draft: false
---
Primary recommended template language:
{# src/_includes/layouts/base.njk #}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="description" content="{{ description or site.description }}"/>
<title>{{ title }} | {{ site.title }}</title>
<link rel="stylesheet" href="/assets/css/main.css"/>
</head>
<body>
{% include "partials/header.njk" %}
<main>
{{ content | safe }}
</main>
{% include "partials/footer.njk" %}
</body>
</html>
{# Conditionals #}
{% if featured %}
<span class="badge">Featured</span>
{% endif %}
{% if posts.length %}
<ul>
{% for post in posts %}
<li>
<a href="{{ post.url }}">{{ post.data.title }}</a>
<time datetime="{{ post.date | dateFormat }}">
{{ post.date | dateFormat }}
</time>
</li>
{% endfor %}
</ul>
{% else %}
<p>No posts yet.</p>
{% endif %}
{# src/_includes/macros/card.njk #}
{% macro card(title, href, description) %}
<article class="card">
<h2><a href="{{ href }}">{{ title }}</a></h2>
{% if description %}
<p>{{ description }}</p>
{% endif %}
</article>
{% endmacro %}
{# Usage #}
{% from "macros/card.njk" import card %}
{{ card(
title="My Post",
href="/blog/my-post/",
description="A brief description"
) }}
Group content for listing pages:
// eleventy.config.js
eleventyConfig.addCollection('posts', (collectionApi) => {
return collectionApi.getFilteredByGlob('src/content/blog/**/*.md');
});
// Tag-based collection (automatic)
// Any content with `tags: posts` in front matter
eleventyConfig.addCollection('posts', (collectionApi) => {
return collectionApi.getFilteredByTag('posts');
});
{# List all posts #}
<ul>
{% for post in collections.posts %}
<li>
<a href="{{ post.url }}">{{ post.data.title }}</a>
</li>
{% endfor %}
</ul>
{# Paginate posts #}
---
pagination:
data: collections.posts
size: 10
alias: posts
---
{% for post in posts %}
...
{% endfor %}
{# Pagination navigation #}
{% if pagination.href.previous %}
<a href="{{ pagination.href.previous }}">Previous</a>
{% endif %}
{% if pagination.href.next %}
<a href="{{ pagination.href.next }}">Next</a>
{% endif %}
Built-in and custom filters:
// eleventy.config.js
// Date formatting
eleventyConfig.addFilter('dateFormat', (date, format = 'medium') => {
return new Intl.DateTimeFormat('en-US', { dateStyle: format }).format(date);
});
// Reading time
eleventyConfig.addFilter('readingTime', (content) => {
const words = content.split(/\s+/).length;
const minutes = Math.ceil(words / 200);
return `${minutes} min read`;
});
// Limit array
eleventyConfig.addFilter('limit', (arr, limit) => arr.slice(0, limit));
// Excerpt
eleventyConfig.addFilter('excerpt', (content, length = 200) => {
const text = content.replace(/<[^>]+>/g, '');
return text.length > length ? text.slice(0, length) + '...' : text;
});
{# Usage #}
<time>{{ post.date | dateFormat('long') }}</time>
<span>{{ post.content | readingTime }}</span>
<p>{{ post.content | excerpt(150) }}</p>
{% for post in collections.posts | limit(5) %}
...
{% endfor %}
Reusable content snippets:
// eleventy.config.js
// Simple shortcode
eleventyConfig.addShortcode('year', () => `${new Date().getFullYear()}`);
// Paired shortcode (with content)
eleventyConfig.addPairedShortcode('callout', (content, type = 'info') => {
return `<aside class="callout callout--${type}">${content}</aside>`;
});
// Async shortcode (for fetching data)
eleventyConfig.addAsyncShortcode('image', async (src, alt) => {
// Image optimization logic here
return `<img src="${src}" alt="${alt}" loading="lazy"/>`;
});
{# Usage #}
<p>Copyright {% year %}</p>
{% callout "warning" %}
This is a warning message.
{% endcallout %}
{% image "hero.jpg", "A descriptive alt text" %}
Control output URLs:
---
# Static permalink
permalink: /custom-url/
# Dynamic permalink
permalink: /blog/{{ page.date | date: '%Y/%m' }}/{{ page.fileSlug }}/
# Disable output (data-only file)
permalink: false
# Multiple outputs (feeds)
permalink:
- /feed.xml
- /feed.json
---
{# src/feed.njk #}
---
permalink: /feed.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{{ site.title }}</title>
<link href="{{ site.url }}/feed.xml" rel="self"/>
<link href="{{ site.url }}/"/>
<updated>{{ collections.posts[0].date | dateFormat }}</updated>
<id>{{ site.url }}/</id>
<author>
<name>{{ site.author.name }}</name>
</author>
{% for post in collections.posts | limit(10) %}
<entry>
<title>{{ post.data.title }}</title>
<link href="{{ site.url }}{{ post.url }}"/>
<updated>{{ post.date | dateFormat }}</updated>
<id>{{ site.url }}{{ post.url }}</id>
<content type="html">{{ post.content | escape }}</content>
</entry>
{% endfor %}
</feed>
# Build command
npx @11ty/eleventy
# Output directory
_site
# .do/app.yaml
name: my-eleventy-site
static_sites:
- name: web
source_dir: /
build_command: npm run build
output_dir: _site
Before deploying:
_data/ is completenpx @11ty/eleventy_site/xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience