Extensible plugin architecture with built-in plugins and support for community plugins, providing a comprehensive system for extending Eleventy's functionality through reusable configuration packages.
Add, configure, and manage Eleventy plugins.
/**
* Add plugin to Eleventy configuration
* @param plugin - Plugin function or object
* @param options - Plugin configuration options
*/
addPlugin(plugin: PluginDefinition, options?: any): void;
/**
* Resolve built-in plugin by name
* @param name - Plugin package name
* @returns Plugin function or Promise<Plugin>
*/
resolvePlugin(name: string): Function | Promise<Function>;
/**
* Check if plugin is already added
* @param plugin - Plugin name or definition
* @returns Whether plugin is registered
*/
hasPlugin(plugin: string | PluginDefinition): boolean;
/**
* Execute code within a plugin namespace to avoid naming conflicts
* @param pluginNamespace - Namespace for plugin
* @param callback - Function to execute in namespace
*/
namespace(pluginNamespace: string, callback: (eleventyConfig: UserConfig) => void): Promise<void>;
interface PluginDefinition {
/** Plugin configuration function */
configFunction?: (eleventyConfig: UserConfig, options?: any) => void | Promise<void>;
/** Plugin package name for identification */
eleventyPackage?: string;
/** Plugin-specific options */
eleventyPluginOptions?: {
/** Only add plugin once (prevents duplicates) */
unique?: boolean;
};
}Built-in Plugin Resolution Names:
@11ty/eleventy/render-plugin@11ty/eleventy/i18n-plugin@11ty/eleventy/html-base-plugin@11ty/eleventy/inputpath-to-url-pluginUsage Examples:
// Add built-in plugins
eleventyConfig.addPlugin(require("@11ty/eleventy").RenderPlugin, {
tagName: "renderTemplate",
filterName: "renderContent"
});
// Add community plugins
eleventyConfig.addPlugin(require("@11ty/eleventy-plugin-syntaxhighlight"), {
theme: "okaidia"
});
// Resolve plugins dynamically
const i18nPlugin = await eleventyConfig.resolvePlugin("@11ty/eleventy/i18n-plugin");
eleventyConfig.addPlugin(i18nPlugin, {
defaultLanguage: "en"
});
// Plugin with namespace
await eleventyConfig.namespace("myPlugin", (eleventyConfig) => {
eleventyConfig.addFilter("myFilter", (content) => content.toUpperCase());
eleventyConfig.addShortcode("myShortcode", () => "Hello from my plugin!");
});
// Check if plugin exists
if (!eleventyConfig.hasPlugin("@11ty/eleventy-plugin-rss")) {
eleventyConfig.addPlugin(require("@11ty/eleventy-plugin-rss"));
}Built-in plugin providing template rendering utilities and shortcodes.
/**
* RenderPlugin configuration
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options
*/
function RenderPlugin(eleventyConfig: UserConfig, options?: RenderPluginOptions): void;
interface RenderPluginOptions {
/** Template tag name for rendering templates */
tagName?: string; // default: "renderTemplate"
/** File template tag name for rendering files */
tagNameFile?: string; // default: "renderFile"
/** Filter name for rendering content */
filterName?: string; // default: "renderContent"
/** Template config instance */
templateConfig?: TemplateConfig;
/** Access global data in renders */
accessGlobalData?: boolean; // default: false
}
/** RenderManager class for programmatic rendering */
class RenderManager {
constructor();
/** Get/set template configuration */
get templateConfig(): TemplateConfig;
set templateConfig(templateConfig: TemplateConfig): void;
/** Initialize render manager */
init(): Promise<boolean>;
/** Configure render manager */
config(callback: (eleventyConfig: UserConfig) => void): any;
/** Get initial global data */
get initialGlobalData(): any;
/** Get data for rendering */
getData(...data: any[]): Promise<object>;
/** Compile template content */
compile(content: string, templateLang: string, options?: any): Promise<Function>;
/** Render compiled template */
render(fn: Function, edgeData?: any, buildTimeData?: any): Promise<any>;
}
/** Named exports from RenderPlugin */
const compileFile: Function; // exported as "File"
const compile: Function; // exported as "String"Usage Examples:
// Add RenderPlugin with custom options
eleventyConfig.addPlugin(RenderPlugin, {
tagName: "render",
filterName: "renderString",
accessGlobalData: true
});
// Using render shortcodes in templates
// {% render "partial.njk", { title: "Hello" } %}
// {% renderFile "includes/header.html" %}
// Using render filter
// {{ "# Hello World" | renderContent: "md" }}
// Programmatic usage
const { RenderManager } = require("@11ty/eleventy");
const renderManager = new RenderManager();
await renderManager.init();
const compiled = await renderManager.compile("Hello {{ name }}", "liquid");
const result = await renderManager.render(compiled, { name: "World" });Built-in plugin for internationalization support with URL and content helpers.
/**
* I18nPlugin configuration
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options
*/
function I18nPlugin(eleventyConfig: UserConfig, options: I18nPluginOptions): void;
interface I18nPluginOptions {
/** Default language code (required) */
defaultLanguage: string;
/** Filter names configuration */
filters?: {
/** URL filter name */
url?: string; // default: "locale_url"
/** Links filter name */
links?: string; // default: "locale_links"
};
/** Error handling mode */
errorMode?: 'strict' | 'allow-fallback' | 'never'; // default: "strict"
}
/** Language utilities class */
class LangUtils {
/** Extract language code from input path */
static getLanguageCodeFromInputPath(filepath: string): string;
/** Extract language code from URL */
static getLanguageCodeFromUrl(url: string): string;
/** Swap language code in string without validation */
static swapLanguageCodeNoCheck(str: string, langCode: string): string;
/** Swap language code in string with validation */
static swapLanguageCode(str: string, langCode: string): string;
}
/** Language comparator utilities */
class Comparator {
/** Check if string is a valid language code */
static isLangCode(code: string): boolean;
/** Check if URL contains specific language code */
static urlHasLangCode(url: string, code: string): boolean;
}Usage Examples:
// Add I18nPlugin
eleventyConfig.addPlugin(I18nPlugin, {
defaultLanguage: "en",
filters: {
url: "locale_url",
links: "locale_links"
},
errorMode: "strict"
});
// Using in templates
// {{ "/about/" | locale_url: "fr" }} → "/fr/about/"
// {{ collections.all | locale_links: "es" }} → filtered collection
// File structure example:
// src/en/index.md
// src/fr/index.md
// src/es/index.md
// LangUtils usage
const { LangUtils } = require("@11ty/eleventy");
const lang = LangUtils.getLanguageCodeFromInputPath("./src/fr/about.md"); // "fr"
const swapped = LangUtils.swapLanguageCode("/en/about/", "fr"); // "/fr/about/"Built-in plugin for applying base href to relative URLs in HTML output.
/**
* HtmlBasePlugin configuration
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options
*/
function HtmlBasePlugin(eleventyConfig: UserConfig, options?: HtmlBasePluginOptions): void;
interface HtmlBasePluginOptions {
/** Base href URL (defaults to eleventyConfig.pathPrefix) */
baseHref?: string;
/** File extensions to process */
extensions?: string; // default: "html"
}
/**
* Transform URL utility function
* @param url - URL to transform
* @param base - Base URL to apply
* @returns Transformed URL
*/
function transformUrl(url: string, base: string): string; // exported as "applyBaseToUrl"Usage Examples:
// Add HtmlBasePlugin
eleventyConfig.addPlugin(HtmlBasePlugin, {
baseHref: "/my-site/",
extensions: "html"
});
// Or use pathPrefix automatically
eleventyConfig.setPathPrefix("/my-site/");
eleventyConfig.addPlugin(HtmlBasePlugin); // Uses pathPrefix
// Transform utility usage
const { transformUrl } = require("@11ty/eleventy");
const transformed = transformUrl("/about/", "/my-site/"); // "/my-site/about/"
// Transforms relative URLs in HTML:
// <a href="/about/">About</a> → <a href="/my-site/about/">About</a>
// <img src="/images/logo.png"> → <img src="/my-site/images/logo.png">Built-in plugins for transforming input paths to URLs.
/**
* Transform version - processes HTML output
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options
*/
function TransformPlugin(eleventyConfig: UserConfig, options?: InputPathToUrlOptions): void;
/**
* Filter version - provides template filter
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options
*/
function FilterPlugin(eleventyConfig: UserConfig, options?: InputPathToUrlOptions): void;
interface InputPathToUrlOptions {
/** File extensions to process */
extensions?: string; // default: "html"
}Usage Examples:
// Add transform version (processes all HTML)
eleventyConfig.addPlugin(TransformPlugin, {
extensions: "html"
});
// Add filter version (use in templates)
eleventyConfig.addPlugin(FilterPlugin);
// Using the filter in templates
// {{ "/src/posts/my-post.md" | inputPathToUrl }}
// Converts input paths to their corresponding URLsBuilt-in plugin for automatically adding id attributes to headings.
/**
* IdAttributePlugin configuration
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options
*/
function IdAttributePlugin(eleventyConfig: UserConfig, options?: IdAttributePluginOptions): void;
interface IdAttributePluginOptions {
/** Custom slugify function */
slugify?: (text: string) => string;
/** CSS selector for elements to process */
selector?: string; // default: "[id],h1,h2,h3,h4,h5,h6"
/** Decode HTML entities in text */
decodeEntities?: boolean; // default: true
/** Check for duplicate IDs */
checkDuplicates?: 'error' | boolean; // default: "error"
/** Filter function for selective processing */
filter?: (element: any) => boolean;
}Usage Examples:
// Add IdAttributePlugin with custom options
eleventyConfig.addPlugin(IdAttributePlugin, {
slugify: (text) => text.toLowerCase().replace(/[^a-z0-9]/g, '-'),
selector: "h1,h2,h3,h4,h5,h6",
checkDuplicates: "error",
filter: (element) => !element.hasAttribute("data-no-id")
});
// Automatically converts:
// <h1>Hello World</h1> → <h1 id="hello-world">Hello World</h1>
// <h2 id="custom">Custom</h2> → <h2 id="custom">Custom</h2> (preserves existing)Re-exported plugin from @11ty/eleventy-plugin-bundle for asset bundling.
/**
* BundlePlugin for CSS/JS bundling and inlining
* Re-exported from @11ty/eleventy-plugin-bundle
*/
const BundlePlugin: PluginDefinition;Usage Examples:
// Add BundlePlugin
eleventyConfig.addPlugin(BundlePlugin);
// Using bundle shortcodes in templates
// {% css %}
// body { margin: 0; }
// {% endcss %}
// {% js %}
// console.log("Hello!");
// {% endjs %}
// {% getBundle "css" %} - outputs bundled CSS
// {% getBundle "js" %} - outputs bundled JavaScriptCreate custom plugins for Eleventy.
/**
* Custom plugin function signature
* @param eleventyConfig - Eleventy configuration instance
* @param options - Plugin options passed by user
*/
type PluginFunction = (eleventyConfig: UserConfig, options?: any) => void | Promise<void>;
/**
* Plugin object format
*/
interface PluginObject {
/** Plugin configuration function */
configFunction: PluginFunction;
/** Plugin package name for identification */
eleventyPackage?: string;
/** Initialization arguments */
initArguments?: any;
/** Plugin options */
eleventyPluginOptions?: {
/** Prevent duplicate plugin registration */
unique?: boolean;
};
}Custom Plugin Examples:
// Simple plugin function
function myCustomPlugin(eleventyConfig, options = {}) {
const { prefix = "my" } = options;
// Add filters
eleventyConfig.addFilter(`${prefix}Filter`, (content) => {
return content.toUpperCase();
});
// Add shortcodes
eleventyConfig.addShortcode(`${prefix}Shortcode`, (text) => {
return `<span class="${prefix}-text">${text}</span>`;
});
// Add transforms
eleventyConfig.addTransform(`${prefix}Transform`, (content, outputPath) => {
if (outputPath && outputPath.endsWith(".html")) {
return content.replace(/\bTODO\b/g, '<mark>TODO</mark>');
}
return content;
});
}
// Plugin object format
const myPluginObject = {
eleventyPackage: "my-custom-plugin",
eleventyPluginOptions: {
unique: true
},
configFunction: (eleventyConfig, options) => {
// Plugin configuration
}
};
// Async plugin
async function myAsyncPlugin(eleventyConfig, options) {
const data = await fetch("https://api.example.com/config");
const config = await data.json();
eleventyConfig.addGlobalData("apiConfig", config);
}
// Usage
eleventyConfig.addPlugin(myCustomPlugin, { prefix: "awesome" });
eleventyConfig.addPlugin(myPluginObject);
eleventyConfig.addPlugin(myAsyncPlugin);interface PluginDefinition {
configFunction?: (eleventyConfig: UserConfig, options?: any) => void | Promise<void>;
eleventyPackage?: string;
eleventyPluginOptions?: {
unique?: boolean;
};
}
interface RenderPluginOptions {
tagName?: string;
tagNameFile?: string;
filterName?: string;
templateConfig?: TemplateConfig;
accessGlobalData?: boolean;
}
interface I18nPluginOptions {
defaultLanguage: string;
filters?: {
url?: string;
links?: string;
};
errorMode?: 'strict' | 'allow-fallback' | 'never';
}
interface HtmlBasePluginOptions {
baseHref?: string;
extensions?: string;
}
interface InputPathToUrlOptions {
extensions?: string;
}
interface IdAttributePluginOptions {
slugify?: (text: string) => string;
selector?: string;
decodeEntities?: boolean;
checkDuplicates?: 'error' | boolean;
filter?: (element: any) => boolean;
}
type PluginFunction = (eleventyConfig: UserConfig, options?: any) => void | Promise<void>;
interface PluginObject {
configFunction: PluginFunction;
eleventyPackage?: string;
initArguments?: any;
eleventyPluginOptions?: {
unique?: boolean;
};
}