Eleventy plugin which provides common filters, shortcodes and transforms for Fluid Project websites.
- Node >= 18
- Eleventy >= 2.0.1
- Infusion >= 4.6.0
Add eleventy-plugin-fluid
to your Eleventy-based static site by running:
npx install-peerdeps eleventy-plugin-fluid
(You can also run npm install --save eleventy-plugin-fluid
, but you'll then need to install the specified infusion
peer dependency in your project as well; the install-peerdeps
command handles both at the same time.)
Then, in your Eleventy configuration file (usually eleventy.eleventyConfig.js
), load the plugin as follows:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(fluidPlugin);
};
For any options passed to eleventy-plugin-fluid
in the configurations described below, you can override the default
rather than merging with it by passing the option with override:
as a prefix to the key. For example, to override the
default options for the css
configuration block, you could do the following:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ "override:css": {
+ // Your options here.
+ }
+ });
};
Note that if you don't override required defaults when using this method, your configuration will not be valid, so proceed with caution if you are using this technique.
eleventy-plugin-fluid
includes configuration for processing and bundling CSS files using LightningCSS,
and JavaScript files using esbuild.
By default, any CSS files found in the ./src/assets/styles/
directory or its children will be processed unless the
filename begins with an underscore (_
). For this reason, if you are using CSS partials via the @import
rule, you should name them according to the pattern _partial.css
to prevent them from being transformed as standalone
files (this convention will be familiar to those who have worked with Sass and Sass partials).
Options for LightningCSS may be modified by passing values to the css
option when registering eleventy-plugin-fluid
in your config:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ css: {
+ cssModules: true,
+ }
+ });
};
Default values are as follows:
let options = {
/* Where should Eleventy look for CSS files to process? */
basePath: `./${eleventyConfig.dir.input || "src"}/assets/styles`,
/* Should CSS files be processed? */
enabled: true,
/* See: https://lightningcss.dev/minification.html */
minify: true,
/* Not yet supported, see https://github.com/fluid-project/eleventy-plugin-fluid/issues/170 */
sourceMap: false,
/* See: https://lightningcss.dev/transpilation.html#draft-syntax */
drafts: {
nesting: true
},
/* A Browserslist configuration string (see: https://browsersl.ist) */
browserslist: "> 1%"
};
If you wish to disable CSS processing altogether, set the enabled
key of the options.css
object to false
.
If you wish to disable Browserslist altogether, you can pass an empty array ([]
) to the browserslist
key.
For more options, see the LightningCSS docs.
By default, any JavaScript files with the .js
extension found in the ./src/assets/scripts/
directory or its children
will be processed with esbuild unless the filename begins with an underscore (_
).
Options for esbuild may be modified by passing values to the js
option when registering eleventy-plugin-fluid
in your config:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ js: {
+ target: "esnext"
+ }
+ });
};
Default values are as follows:
let options = {
/* Where should Eleventy look for JavaScript files to process? */
basePath: `./${eleventyConfig.dir.input || "src"}/assets/scripts`,
/* Should JavaScript files be processed? */
enabled: true,
/* See: https://esbuild.github.io/api/#minify */
minify: true,
/* See: https://esbuild.github.io/content-types/#javascript */
target: "es2020",
basePath: `./${eleventyConfig.dir.output || "_site"}/assets/styles`
};
If you wish to disable JavaScript processing altogether, set the enabled
key of the options.js
object to false
.
eleventy-plugin-fluid
adds support for localization using Eleventy's i18n plugin
and eleventy-plugin-i18n-gettext
for string translation.
By default, the following languages are configured:
en
en-CA
en-US
es
fa
fr
pt-br
You can add support for additional languages by passing values to the supportedLanguages
option when registering
eleventy-plugin-fluid
in your config:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ supportedLanguages: {
+ de: {
+ // The slug which will be used in URLs to content in this language.
+ slug: "de",
+ // The slug which will be used to localize UIO (see: https://docs.fluidproject.org/infusion/development/localizationinthepreferencesframework#specifying-a-localization)
+ uioSlug: "de",
+ // The direction of the language.
+ dir: "ltr",
+ // The endonym of the language.
+ name: "Deutsch"
+ }
+ }
+ });
};
eleventy-plugin-fluid
provides the following global data:
{
"defaultLanguage": "en",
"defaultLanguageDir": "ltr",
"supportedLanguages": {
"en": {
"slug": "en",
"uioSlug": "en",
"dir": "ltr",
"name": "English"
},
"en-CA": {
"slug": "en-ca",
"uioSlug": "en_CA",
"dir": "ltr",
"name": "English (Canada)"
},
"en-US": {
"slug": "en-us",
"uioSlug": "en_US",
"dir": "ltr",
"name": "English (United States)"
},
"es": {
"slug": "es",
"uioSlug": "es",
"dir": "ltr",
"name": "Español"
},
"fa": {
"slug": "fa",
"uioSlug": "fa",
"dir": "rtl",
"name": "فارسی"
},
"fr": {
"slug": "fr",
"uioSlug": "fr",
"dir": "ltr",
"name": "Français"
},
"pt-BR": {
"slug": "pt-br",
"uioSlug": "pt_BR",
"dir": "ltr",
"name": "Português (Brasil)"
}
}
}
The defaultLanguage
can be overridden by passing a new value to the defaultLanguage
options key when registering
eleventy-plugin-fluid
.
By default, eleventy-plugin-fluid
also configures a localesDirectory
for eleventy-plugin-i18n-getttext
as ./src/_locales
. This can be overridden by passing a new value to the
localesDirectory
options key when registering eleventy-plugin-fluid
.
eleventy-plugin-fluid
also provides two localization-related helpers:
generatePermalink
is used to generate localized permalinks for a collection type,
with full support for pagination. Here's an example, as used in an 11tydata.js
file:
import { EleventyI18nPlugin } from "@11ty/eleventy";
import { generatePermalink } from "eleventy-plugin-fluid";
import { _ } from "eleventy-plugin-i18n-gettext";
export default {
layout: "layouts/base.njk",
eleventyComputed: {
lang: data => EleventyI18nPlugin.LangUtils.getLanguageCodeFromInputPath(data.page.inputPath),
langDir: data => data.supportedLanguages[data.lang].dir,
locale: data => data.lang,
permalink: data => {
const locale = data.locale;
return generatePermalink(data, "pages", _(locale, "pages"), _(locale, "page"));
}
}
};
In this example, eleventy-plugin-i18n-gettext
is used
to localize the URL path for the collection. The _()
method provided by eleventy-plugin-i18n-gettext
requires a
variable called locale
as its first parameter (see this issue).
localizeData
is used to localize directory data
for a directory of content in a specific language (where the directory name is the language code). Here's an example,
as used in an 11tydata.js
file:
import { localizeData } from "eleventy-plugin-fluid";
export default () => {
return fluidPlugin.localizeData({}, __dirname);
};
This helper is a wrapper for i18n.enhance11tydata
.
If you don't need string translation features in your project, you can disable string translation by setting the i18n
option to false when registering eleventy-plugin-fluid
in your config:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ i18n: false
+ });
};
Note that if you do this, you will need to remove any uses of the localizeData
helper or
eleventy-plugin-i18n-gettext
functions in your
project.
For additional information on setting up localization/internationalization, see:
eleventy-plugin-fluid
amends Eleventy's default Markdown configuration
as follows (for more information see markdown-it):
{
"html": true,
"linkify": true,
"typographer": true
}
Options for Markdown may be modified by passing values to the markdown
option when registering eleventy-plugin-fluid
in your config:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ markdown: {
+ options: {
+ breaks: "true"
+ }
+ }
+ });
};
You can also enable markdown-it
plugins when
registering eleventy-plugin-fluid
as follows:
import fluidPlugin from "eleventy-plugin-fluid";
+ import markdownItDefList from "markdown-it-deflist";
+ import markdownItEmoji from "markdown-it-emoji";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ markdown: {
+ plugins: [
+ // The imported plugin.
+ markdownItDefList,
+ // The imported plugin and an options object for the plugin.
+ [markdownItEmoji, {}]
+ ]
+ }
+ });
};
All examples use the Nunjucks template language. Eleventy supports a number of other template languages; see Eleventy's documentation on filters for usage with different template languages.
Formats a date string.
{{ "Sun Jun 21 2020 18:00:00 GMT-0300 (Atlantic Daylight Time)" | formatDate }}
Output: June 21st, 2020
Optionally, a locale
parameter
can be supplied to format a date in a locale other than English.
{{ "Sun Jun 21 2020 18:00:00 GMT-0300 (Atlantic Daylight Time)" | formatDate('fr') }}
Output: 21 juin 2020
Formats a date string to ISO 8601 format.
{{ "Sun Jun 21 2020 18:00:00 GMT-0300 (Atlantic Daylight Time)") | isoDate }}
Output: 2020-06-21T21:00:00.000Z
Trims an array to the specified length.
{{ ["a", "b", "c"] | limit(2) | dump }}
Output: ["a", "b"]
Processes an input string using Markdown.
{{ "A paragraph with some _emphasis_." | markdown | safe }}
Output: <p>A paragraph with some <em>emphasis</em>.</p>\n
Processes an input string by lowercasing it, replacing whitespace with hyphens, and stripping special characters to create a URL-safe version.
NOTE: This filter has been completely removed as of eleventy-plugin-fluid 3.0.
Instead, use Eleventy's slugify
filter.
Splits an input string into an array based on a provided delimiter.
{{ "a,b,c" | split(",") | dump }}
Output: ["a", "b", "c"]
All examples use the Nunjucks template language. Eleventy supports a number of other template languages; see Eleventy's documentation on shortcodes for usage with different template languages.
Outputs a <figure>
element with a <figcaption>
. The first and second parameters in the opening tag of the shortcode
are the image URL and alternative text respectively. Caption content, which can use Markdown, goes in between the
opening and closing shortcode tags.
{% figure "/assets/image.png", "A description of this image." %}
An illustration of something, found [here](https://example.com).
{% endfigure %}
Output:
<figure>
<img src="/assets/image.png" alt="A description of this image." />
<figcaption>
<p>An illustration of something, found <a href="https://example.com">here</a>.</p>
</figcaption>
</figure>
Outputs links to the required CSS assets for an instance of Infusion User Interface Options. Use this when you want the out-of-the-box/drop-in experience with UI Options styles overriding the site styles. This is the quickest way to start, but harder to customize and fit with your site's own styling.
{% uioStyles %}
Result:
<link href="/lib/infusion/src/framework/core/css/fluid.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/Enactors.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/PrefsEditor.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/SeparatedPanelPrefsEditor.css" rel="stylesheet">
Outputs links to the required CSS assets for an instance of Infusion User Interface Options. This only includes the related CSS Custom Properties. Use this when you want to have control over how the enactor styles are applied.
See: Integrating UI Options Styling Preferences
{% uioStyleProps %}
Result:
<link href="/lib/infusion/src/framework/core/css/fluid.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/Contrast_base.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/EnhanceInputs_base.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/Font_base.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/PrefsEditor.css" rel="stylesheet">
<link href="/lib/infusion/src/framework/preferences/css/SeparatedPanelPrefsEditor.css" rel="stylesheet">
Outputs links to the required JavaScript assets for an instance of Infusion User Interface Options.
{% uioScripts %}
Result:
<link rel="preload" href="/lib/infusion/infusion-uio.js" as="script" />
<script src="/lib/infusion/infusion-uio.js"></script>
Outputs the required HTML template markup for an instance of Infusion User Interface Options. This should used
directly after the opening <body>
tag.
{% uioTemplate %}
Result:
<div class="flc-prefsEditor-separatedPanel fl-prefsEditor-separatedPanel">
<div class="fl-panelBar fl-panelBar-smallScreen" id="Editorspace">
<span class="fl-prefsEditor-buttons">
<button class="flc-slidingPanel-toggleButton fl-prefsEditor-showHide"> Show/Hide</button>
<button class="flc-prefsEditor-reset fl-prefsEditor-reset"><span class="fl-icon-undo"></span> Reset</button>
</span>
</div>
<div class="flc-slidingPanel-panel"></div>
<div class="fl-panelBar fl-panelBar-wideScreen">
<span class="fl-prefsEditor-buttons">
<button class="flc-slidingPanel-toggleButton fl-prefsEditor-showHide"> Show/Hide</button>
<button class="flc-prefsEditor-reset fl-prefsEditor-reset"><span class="fl-icon-undo"></span> Reset</button>
</span>
</div>
</div>
If you want to use a custom integration of User Interface Options, you can insert the required markup directly into your base template.
Outputs the required JavaScript to initialize an instance of Infusion User Interface Options. This should used
directly before the closing </body>
tag.
{% uioInit %}
Result:
<script>
fluid.uiOptions.multilingual(".flc-prefsEditor-separatedPanel", {
"auxiliarySchema": {
"terms": {
"templatePrefix": "/lib/infusion/src/framework/preferences/html",
"messagePrefix": "/lib/infusion/src/framework/preferences/messages"
},
"fluid.prefs.tableOfContents": {
"enactor": {
"tocTemplate": "/lib/infusion/src/components/tableOfContents/html/TableOfContents.html",
"tocMessage": "/lib/infusion/src/framework/preferences/messages/tableOfContents-enactor.json",
"ignoreForToC": {
"ignoreClass": ".flc-toc-ignore"
}
}
}
},
"prefsEditorLoader": {
"lazyLoad": true
}
});
</script>
Optionally, to support localization, you can pass in locale and direction arguments.
{% uioInit "fa", "rtl" %}
Result:
<script>
fluid.uiOptions.multilingual(".flc-prefsEditor-separatedPanel", {
"auxiliarySchema": {
"terms": {
"templatePrefix": "/lib/infusion/src/framework/preferences/html",
"messagePrefix": "/lib/infusion/src/framework/preferences/messages"
},
"fluid.prefs.tableOfContents": {
"enactor": {
"tocTemplate": "/lib/infusion/src/components/tableOfContents/html/TableOfContents.html",
"tocMessage": "/lib/infusion/src/framework/preferences/messages/tableOfContents-enactor.json",
"ignoreForToC": {
"ignoreClass": ".flc-toc-ignore"
}
}
}
},
"prefsEditorLoader": {
"lazyLoad": true
},
"locale": "fa",
"direction": "rtl"
});
</script>
If you want to use a custom integration of User Interface Options, you can insert the required script tag directly into your base template.
eleventy-plugin-fluid
adds the Eleventy WebC plugin for WebC support. By
default, the plugin will look for WebC components in ./src/_components/**/*.webc
. This, and other options,
can be modified when registering eleventy-plugin-fluid
:
import fluidPlugin from "eleventy-plugin-fluid";
export default function (eleventyConfig) {
- eleventyConfig.addPlugin(fluidPlugin);
+ eleventyConfig.addPlugin(fluidPlugin, {
+ webc: {
+ components: "./src/_includes/**/*.webc"
+ }
+ });
};
eleventy-plugin-fluid
adds an HTML minify transform to output files with a .html
extension which minifies them
using html-minifier
.
By default, eleventy-plugin-fluid
copies the required assets for an instance of
Infusion User Interface Options into the lib/infusion
directory of the build directory.
-
BREAKING:
eleventy-plugin-fluid
v3.x requires Eleventy v3.x and is written in ESM. See this post for upgrade information and guidance. -
BREAKING: The
markdown
filter has been removed. Please use the Eleventy Render plugin'srenderContent
filter instead.{% set string = "**Hi!** %} - {{ string | markdown | safe }} + {{ string | renderContent('md') | safe }}
-
BREAKING: The
renderString
shortcode has been removed. Please use the Eleventy Render plugin'srenderContent
filter instead:{% set string = "**Hi!** %} - {% renderString string, 'md' %} + {{ string | renderContent('md') | safe }}
-
BREAKING: The Eleventy WebC plugin is no longer included. If your project uses WebC, please follow the installation instructions to add the plugin.
-
BREAKING: Sass support is no longer included. If your project uses Sass, please install
eleventy-plugin-fluid-sass
.
This package uses Conventional Commits, enforced with commitlint. This facilitates releasing new versions of the package via Release Please. To cut a release, merge the current release pull request.
This will tag an appropriate semantic version based on the nature of the recent commits to the project and update the changelog.
You will then need to publish the updated version to the npm registry. This requires an npm account with appropriate maintainer permissions. To publish the package, run:
npm publish
For more information on publishing to npm, see the npm publish documentation.
eleventy-plugin-fluid
is based on other publicly available software, categorized by license: