Content of /tricks/ section is open-source.
You're welcome to:
Content of /tricks/ section is open-source.
You're welcome to:
Not sure where to begin? Start with a minimal template:
| Repo | Stats |
npm Dependencies | Custom CSS |
Custom JS |
Custom Templates |
CMS Included? |
|---|---|---|---|---|---|---|
| 3 ♻️ | 0 ♻️ uses pico.css & bricks[.css] | 0 ♻️ uses eleventy-bricks | ~15 lines ♻️ uses bricks[.liquid] | Sveltia CMS | ||
| ~10 | ~30 lines ♻️ uses tailwind & bricks[.css] | 0 ♻️ uses eleventy-bricks | ~10 lines ♻️ uses bricks[.njk] | Sveltia CMS | ||
| ~10 | ~300 lines | ~200 lines | ~200 lines | — | ||
| ~15 | ~200 lines | ~300 lines | ~250 lines | not included, but documented | ||
| Not up-to-date: | ||||||
| ~10 | ~150 lines | ~130 lines | ~250 lines | Sveltia CMS | ||
| Not so minimal: | ||||||
| ~25 ⚠️ | ~1000 lines ⚠️ | ~30 files ⚠️ | ~20 files | Front Matter CMS (local use only) | ||
| ~40 ⚠️ | ~40 files ⚠️ Tailwind config for CUBE CSS | ~40 files ⚠️ | ~40 files ⚠️ | — | ||
| ~5 ♻️ | ~25 files ⚠️ | ~15 files | ~15 files | — | ||
| ~15 | ~30 files ⚠️ | ~10 files | ~10 files | — |
ps aux | grep eleventy
pkill -f eleventy
You can even combine it with other processes hanging around:
ps aux | grep -E 'eleventy|tailwind|.bin/serve'
pkill -f tailwind
pkill -f .bin/serve
This package provides a pre-configured do folder setup that helps organize your development workflow using npm workspaces. The do folder contains scripts for building and running your Eleventy project.
Installation:
npm install @anydigital/eleventy-bricks
do to symlink the do/package.json within:mkdir do
cd ./do
ln -s ../node_modules/@anydigital/eleventy-bricks/src/do/package.json
do folder as npm workspace in your root package.json:{
...
"workspaces": ["do"],
"scripts": {
"start": "npm -w do run start",
"stage": "npm -w do run stage",
"build": "npm -w do run build"
},
...
}
Done! 🎉 Now you can run:
npm start to start 11ty dev server with live reload and Tailwind watch modenpm run stage to build and serve production-like site locallynpm run build to finally build the site for productionLiving example: /anydigital/sveleven
Benefits:
eleventy.config.js The package includes a fully-configured Eleventy config file eleventy.config.js that you can symlink to your project to get:
Benefits of symlinking:
Installation as simple as:
npm install @anydigital/eleventy-bricks
ln -s ./node_modules/@anydigital/eleventy-bricks/src/eleventy.config.js
siteData helper 🧩 Install via Plugin — or copy-paste from
src/siteData.js
Adds global site data to your Eleventy project, providing commonly needed values that can be accessed in all templates:
| Variable | Value |
|---|---|
{{ site.year }} |
The current year as a number (e.g., 2026) |
{{ site.prod }} |
Boolean indicating if running in production mode (true for eleventy build, false for eleventy serve) |
autoLinkFavicons transformer 🧩 Install via Plugin — or copy-paste from
src/processors/autoLinkFavicons.js
Automatically adds favicon images from Google's favicon service to links that display plain URLs or domain names. This processor processes all HTML output files and adds inline favicon images next to link text that appears to be a plain URL.
Why use this? When you have links in your content that display raw URLs or domain names (like https://example.com/page), adding favicons provides a visual indicator of the external site. This processor automatically detects these plain-text URL links and enhances them with favicon images, making them more visually appealing and easier to recognize.
How it works:
<a> tagsExample:
Before processing:
<a href="https://github.com/anydigital/eleventy-bricks">https://github.com/anydigital/eleventy-bricks</a>
After processing:
<a href="https://github.com/anydigital/eleventy-bricks" class="whitespace-nowrap" target="_blank">
<i><img src="https://www.google.com/s2/favicons?domain=github.com&sz=32" /></i>
<span>/anydigital/eleventy-bricks</span>
</a>
Rules:
http:///https://)https://www.google.com/s2/favicons?domain=DOMAIN&sz=32target="_blank" to the processed links (only if not already present)whitespace-nowrap class to the link<span> element<i> tag for easy styling🧩 Install via Plugin — or copy-paste from
src/processors/markdown.js
Prevents Nunjucks syntax from being processed in Markdown files by automatically wrapping {{, }}, {%, and %} with {% raw %} tags.
Why use this? When writing documentation or tutorials about templating in Markdown files, you often want to show Nunjucks/Liquid syntax as literal text. This preprocessor automatically escapes these special characters so they display as-is instead of being processed by the template engine.
Example:
Before mdAutoRawTags, writing this in Markdown:
### Using {{ variable }} to output variables
Would try to process {{ variable }} as a template variable. With mdAutoRawTags, it displays exactly as written.
🧩 Install via Plugin — or copy-paste from
src/processors/markdown.js
Automatically converts \n sequences to <br> tags in Markdown content. This is particularly useful for adding line breaks inside Markdown tables where standard newlines don't work.
Why use this? Markdown tables don't support multi-line content in cells. By using \n in your content, this preprocessor will convert it to <br> tags, allowing you to display line breaks within table cells and other content.
Example:
In your Markdown file:
| Column 1 | Column 2 |
| ---------------------- | --------------------------------- |
| Line 1\nLine 2\nLine 3 | Another cell\nWith multiple lines |
Will render as:
<td>Line 1<br />Line 2<br />Line 3</td>
<td>Another cell<br />With multiple lines</td>
Note: This processes literal \n sequences (backslash followed by 'n'), not actual newline characters. Type \n in your source files where you want line breaks.
This is a modern fork of the original extension. It is specifically designed to solve the "11ty problem" where you mix Nunjucks and HTML.
Why it's better: It injects Nunjucks grammar directly into the standard HTML grammar. This means you get full Nunjucks highlighting and the editor still knows it's an HTML file, giving you better Emmet and CSS autocompletion.
No Config: It works out of the box without needing to manually map file associations in your settings.
🧩 Install /prettier/prettier-vscode (if not yet)
Install a compatible Prettier plugin for your project, for example:
npm i -D prettier-plugin-jinja-template
jinja-template works just fine with .njk via .html override:{
"plugins": ["prettier-plugin-jinja-template"],
"overrides": [
{
"files": ["*.njk", "*.html"],
"options": {
"parser": "jinja-template"
}
}
]
}
PRO TIP: If you already use /anydigital/bricks, it’s even easier. You can simply:
ln -s ./node_modules/@anydigital/bricks/.prettierrc.json
Per official .njk documentation:
sort(arr, reverse, caseSens, attr)
Sort arr with JavaScript's arr.sort function. If reverse is true, result will be reversed. Sort is case-insensitive by default, but setting caseSens to true makes it case-sensitive. If attr is passed, will compare attr from each item.
But you can actually do this trick:
{% for item in array | sort(attribute='weight') %}
...
{% endfor %}
.md file w/o its Front Matter in 11ty {# first, get the raw content using `html` as plain-text engine #}
{% set _eval = "{% renderFile './YOUR_FILE.md', {}, 'html' %}" %}
{% set _raw_md = _eval | renderContent('njk') %}
{# then, remove the front matter using regex, and render using `md` #}
{{ _raw_md | replace(r/^---[\s\S]*?---/, '') | renderContent('md') | safe }}
.njk & .liquid) The package includes reusable templates in the ./src/bricks/ directory. These are useful for common web development patterns.
npm install @anydigital/bricks
cd ./src/_includes
ln -s ../../node_modules/@anydigital/bricks/src/bricks
__html.*) A unified base HTML template bricks/__html.{njk|liquid} that provides the essential document structure with built-in support for modern web best practices.
Usage:
{% extends 'bricks/__html.njk' %}
{% block body %}
<!-- YOUR page content -->
{% endblock %}
Example: /anydigital/sveleven/blob/main/src/_theme/__layout.njk
{% capture body %}
<!-- YOUR page content -->
{% endcapture %}
{% include 'bricks/__html' %}
Example: /anydigital/sveleven/blob/main/src/_theme/__layout.liquid
Features:
en, configurable via site.lang)viewport-fit=cover for notched devices|)/favicon.ico)site.styles arraysite.inline_styles array (joined with newlines in a <style> tag)site.scripts array (with defer attribute)site.inline_scripts array (joined with newlines in a <script type="module"> tag)content_for_header_gtm.{njk|liquid} template for both <head> and <body> when site.prod and site.gtm_id are set)Variables:
body - The page content to be rendered inside the <body> tag (required)title - Page title (optional, will be stripped of HTML tags)site.title - Site title for the title suffixsite.lang - Language code (optional, defaults to 'en')site.styles - Array of stylesheet URLs (optional)site.inline_styles - Array of inline CSS strings (optional)site.scripts - Array of script URLs (optional)site.inline_scripts - Array of inline JavaScript strings (optional)content_for_header - Custom HTML for the head section (optional)site.gtm_id - Google Tag Manager ID (optional)site.prod - Boolean flag for production environment (optional)_nav.*) A navigation template bricks/_nav.{njk|liquid} that renders a list of navigation links with proper accessibility attributes.
Parameters:
nav_pages - Array of navigation page objects with url and title propertiescurrent_url - The URL of the current page (used to set aria-current="page")Usage example with Eleventy Navigation plugin:
{% assign nav_pages = collections.all | eleventyNavigation %}
{% render 'bricks/_nav', nav_pages: nav_pages, current_url: page.url %}
Output:
<nav>
<a href="/">Home</a>
<a href="/about" aria-current="page">About</a>
<a href="/contact">Contact</a>
</nav>
_gtm.*) A template bricks/_gtm.{njk|liquid} for embedding Google Tag Manager scripts in your pages.
Parameters:
site.gtm_id - Your Google Tag Manager container ID (e.g., GTM-XXXXXXX)site.prod - Boolean flag to enable GTM only in productionfor_body - Boolean flag (default: false). When false, renders the script tag for the <head>. When true, renders the noscript fallback for the <body>.Note: This template is automatically included when using __html.liquid. You only need to manually render it if you're not using that base template, see examples:
.njk & .liquid from if 🧩 Install via Plugin — or copy-paste from
src/filters/if.js
An inline conditional/ternary operator filter that returns one value if a condition is truthy, and another if it's falsy. Similar to Nunjucks' inline if syntax, it is especially useful in .liquid templates.
Features:
trueValue if condition is truthy, otherwise returns falseValue{} as falsyfalseValue is an empty string if not providedExamples:
{# Basic usage (defaults to empty string) #}
<div class="{{ 'active' | if: isActive | default: 'inactive' }}">Status</div>
{# Toggle CSS classes #}
<button class="{{ 'btn-primary' | if: isPrimary | default: 'btn-secondary' }}">
Click me
</button>
{# Display different text #}
<p>{{ 'Online' | if: user.isOnline, 'Offline' }}</p>
{# Use with boolean values #}
{% set isEnabled = true %}
<div>{{ 'Enabled' | if: isEnabled, 'Disabled' }}</div>
{# Conditional attribute values #}
<input type="checkbox" {{ 'checked' | if: isChecked }}>
{# With numeric values #}
<span class="{{ 'has-items' | if: items.length }}">
{{ items.length }} items
</span>
{# Chain with other filters #}
{% set cssClass = 'featured' | if: post.featured | upper %}
merge 🧩 Install via Plugin — or copy-paste from
src/filters/merge.js
A filter that merges arrays or objects together, similar to Twig's merge filter. For arrays, it concatenates them. For objects, it performs a shallow merge where later values override earlier ones.
Why use this? When working with data in templates, you often need to combine multiple arrays or objects. The merge filter provides a clean way to merge data structures without writing custom JavaScript, making it easy to combine collections, merge configuration objects, or aggregate data from multiple sources.
Examples:
{# Merge configuration objects #}
{% set defaultConfig = { theme: 'light', lang: 'en' } %}
{% set userConfig = { theme: 'dark' } %}
{% set finalConfig = defaultConfig | merge(userConfig) %}
{# Result: { theme: 'dark', lang: 'en' } #}
{# Merge page metadata with defaults #}
{% set defaultMeta = {
author: 'Site Admin',
category: 'general',
comments: false
} %}
{% set pageMeta = defaultMeta | merge(page.data) %}
attr_set 🧩 Install via Plugin — or copy-paste from
src/filters/attr_set.js
A filter that creates a new object with an overridden attribute value. This is useful for modifying data objects in templates without mutating the original. Or even constructing an object from scratch.
.liquid? {% assign _ctx = null | attr_set: 'collections', collections %}
{{ ... | renderContent: 'liquid,md', _ctx }}
attr_concat 🧩 Install via Plugin — or copy-paste from
src/filters/attr_concat.js
A filter that concatenates values to an attribute array, returning a new object with the combined array. Useful for adding items to arrays like tags, classes, or other list-based attributes.
Why use this? When working with objects that have array attributes (like tags), you often need to add additional values without mutating the original object. The attr_concat filter provides a clean way to combine existing array values with new ones, automatically handling duplicates.
Features:
.liquid), or single valuesTBC: Supports nested attributes (e.g., data.tags).njk: {% set enhancedPost = post | attr_concat('tags', ['featured', 'popular']) %}
PRO Example: Add scripts and styles to the site object in .liquid: {% capture _ %}[
"https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism-tomorrow.min.css",
"https://cdn.jsdelivr.net/npm/prismjs@1/plugins/treeview/prism-treeview.min.css",
"https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7/css/all.min.css",
"/styles.css"
]{% endcapture %}
{% assign site = site | attr_concat: 'styles', _ %}
{% capture _ %}[
"https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js",
"https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js",
"https://cdn.jsdelivr.net/npm/prismjs@1/plugins/treeview/prism-treeview.min.js"
]{% endcapture %}
{% assign site = site | attr_concat: 'scripts', _ %}
attr_includes 🧩 Install via Plugin — or copy-paste from
src/filters/attr_includes.js
A filter that filters a list of items by checking if an attribute array includes a target value. Supports nested attribute names using dot notation.
Why use this? When working with Eleventy collections, you often need to filter items based on tags or other array attributes in front matter. The attr_includes filter provides a flexible way to filter by any array attribute, with support for nested properties using dot notation.
#javascript tag {% set js_posts = collections.all | attr_includes('data.tags', '#javascript') %}
{% for post in js_posts %}
<h2>{{ post.data.title }}</h2>
{% endfor %}
fetch 🧩 Install via Plugin — or copy-paste from
src/filters/fetch.js
A filter that fetches content from remote URLs or local files. For remote URLs, it uses @11ty/eleventy-fetch to download and cache files. For local paths, it reads files relative to the input directory.
Why use this? When building static sites, you often need to include content from external sources or reuse content from local files. The fetch filter provides a unified way to retrieve content from both remote URLs and local files, with automatic caching for remote resources to improve build performance.
Requirements: This filter requires the @11ty/eleventy-fetch package to be installed:
npm install @11ty/eleventy-fetch
NOTE:If@11ty/eleventy-fetchis not installed, this filter will not be available. The plugin automatically detects whether the package is installed and only enables the filter if it's present.
Features:
http:// or https://) or a local file path (relative to the input directory):
@11ty/eleventy-fetch
[input-dir]/_downloads/ directory@11ty/eleventy-fetch is installedUse Cases:
NOTE:The filter returns raw text content. Use Eleventy's built-in filters like| safe,| markdown, or| fromJsonto process the content as needed.
Examples:
{# Fetch and display remote content #}
{% set readme = "https://raw.githubusercontent.com/user/repo/main/README.md" | fetch %}
<div class="readme">
{{ readme | markdown | safe }}
</div>
{# Fetch JSON data from API #}
{% set data = "https://api.example.com/data.json" | fetch %}
{% set items = data | fromJson %}
{% for item in items %}
<p>{{ item.title }}</p>
{% endfor %}
{# Include local file content #}
{% set changelog = "CHANGELOG.md" | fetch %}
{{ changelog | markdown | safe }}
{# Fetch CSS from CDN and inline it #}
<style>
{{ "https://cdn.example.com/styles.css" | fetch }}
</style>
{# Reuse content across pages #}
{% set sharedContent = "_includes/shared/footer.html" | fetch %}
{{ sharedContent | safe }}
section 🧩 Install via Plugin — or copy-paste from
src/filters/section.js
A filter that extracts a named section from content marked with HTML comments. This is useful for splitting a single content file (like a Markdown post) into multiple parts that can be displayed and styled independently in your templates.
Usage:
post.md):⚠️ NOTE: The ¡ symbol is used instead of ! only to give examples below. Use ! in your actual content files.
# My Post
<¡--section:intro-->
This is the introduction that appears at the top of the page.
<¡--section:main-->
This is the main body of the post with all the details.
<¡--section:summary,sidebar-->
This content appears in both the summary and the sidebar!
{# Get the intro section #}
<div class="page-intro">
{{ content | section('intro') | safe }}
</div>
{# Get the main section #}
<article>
{{ content | section('main') | safe }}
</article>
{# Get the sidebar section #}
<aside>
{{ content | section('sidebar') | safe }}
</aside>
Features:
<¡--section:name1,name2--><¡--section*--> marker or the end of the fileSyntax Rules:
<¡--section:NAME--> or <¡--section:NAME1,NAME2--><¡--section*--> marker or end of fileremove_tag 🧩 Install via Plugin — or copy-paste from
src/filters/remove_tag.js
A filter that removes a specified HTML element from provided HTML content. It removes the tag along with its content, including self-closing tags.
Why use this? When working with content from external sources or user-generated content, you may need to strip certain HTML tags for security or presentation purposes. The remove_tag filter provides a simple way to remove unwanted tags like <script>, <style>, or any other HTML elements from your content.
Features:
<br />, <img />)Security note: While this filter can help sanitize HTML content, it should not be relied upon as the sole security measure. For critical security requirements, use a dedicated HTML sanitization library on the server side before content reaches your templates.
{% set cleanContent = htmlContent | remove_tag('script') %}
{{ cleanContent | safe }}
strip_tag 🧩 Install via Plugin — or copy-paste from
src/filters/strip_tag.js
A filter that strips a specified HTML element from content while keeping its inner content intact. Only the opening and closing tags are removed; everything inside the tag is preserved in place.
Why use this? When rendering HTML from a CMS or external source you sometimes need to unwrap a specific element (e.g. remove a wrapping <div> or <section>) without losing the content it contains. Unlike remove_tag, which discards the entire element and its content, strip_tag surgically removes only the tags themselves.
Features:
<div> from content {% set unwrapped = htmlContent | strip_tag('div') %}
{{ unwrapped | safe }}
Input:
<div class="wrapper">
<p>Hello</p>
<p>World</p>
</div>
Output:
<p>Hello</p>
<p>World</p>
Projects that provide a quick starting point for Eleventy sites:
Minimally maintained:
Webmentions:
GraphQL:
This page follows a similar structure to /docs/projects
Featured in:
© 2025–2026