Skip to content

Build awesome configuration

How the build runs when you publish, and what you can add to it: Eleventy plugins and shortcodes.

How the build works

Silex publishes your website to a Git repository, then the hosting platform's CI builds it. Silex writes the site files into the public/ folder of the repository, and generates the build script. build awesome (the new name of Eleventy, pinned version 3.1.6) turns public/ into _site/, and _site/ is what gets deployed.

The build step runs these commands:

npx @11ty/eleventy@3.1.6 --input=public --output=_site
cp -R public/css public/assets _site/ 2>/dev/null || true

There is no Eleventy config file in this command. Eleventy is run with command line options, and it looks for a config file at the root of the repository (see Add a plugin below).

Silex adds a front matter at the top of each page, with or without a data source. It sets the permalink of the page: index.html is published as /index.html, and about.html as /about/index.html. Eleventy then renders every page as a Liquid template. Text in your pages that looks like Liquid, such as {{ ... }} or {% ... %}, is read as Liquid.

On a website with a data source, a page that uses data also gets a <page>.11tydata.mjs file next to it, which loads this data at build time.

The build only starts when you publish

The CI pipeline runs when Silex creates a tag named _silex_<timestamp>, which happens at each publication. It also runs on a trigger, api, web or schedule pipeline. It does not run on a normal push. If you edit build.json directly on the forge and push, nothing is built: publish from Silex. Silex then writes build.sh again from your build.json. A pipeline that you start by hand from the platform interface uses the build.sh of the last publication.

Add a plugin

You do not need to be a developer to add a plugin. It takes three small files that you copy and paste into your website repository on GitLab, from your browser. This section explains what happens, then gives every step for one plugin: optimized images.

Eleventy and the GitLab build, in simple words

Eleventy is the tool that makes your final website from the files that Silex publishes. Silex sends your pages, styles and images to GitLab. Eleventy reads them and writes the final site. Eleventy now has a new name: Build Awesome. You see both names, in Silex and on the Eleventy website.

An Eleventy plugin adds one more job to Eleventy. For example, it makes your images smaller while it makes your site. Plugins are free packages, shared on npm, the package library of JavaScript. An Eleventy plugin is not a Silex plugin: it runs in the build on GitLab, not in the Silex editor. Silex plugins are on the page Using plugins.

The GitLab build is where Eleventy runs. Each time you publish from Silex, GitLab runs the build commands by itself, on its own servers. This is called a pipeline. When the pipeline is done, GitLab puts the result online with GitLab Pages. In your project on GitLab, Build → Pipelines shows the state of each pipeline: running, passed or failed.

Learn more

Before you start

  • Publish your website from Silex to GitLab at least once. The first publication creates the build.json file.
  • On GitLab, open your project and select Code → Repository. You see the files of your website, among them the public folder, build.json, build.sh and .gitlab-ci.yml. This list is the root of the repository.

All the files of this section go at the root of the repository, next to build.json. Never in the public folder.

Step by step: optimized images

This plugin makes smaller versions of the images of your website, in WebP and in their original format. It is the official image plugin of Eleventy, Eleventy Image. Only the images that you add as image elements change. Background images, set in the Style panel, do not change.

Step 1. Create package.json. This file tells the build which plugin to download.

  1. On GitLab, open your project, then Code → Repository. Stay at the root, do not open the public folder.
  2. Next to the name of the folder, above the list of files, select the plus icon (+), then New file.
  3. In the file name field, type package.json.
  4. Copy this content and paste it in the editor:

    {
      "type": "module",
      "dependencies": {
        "@11ty/eleventy-img": "^7.1.1"
      }
    }
    
  5. Select Commit changes. Write a short Commit message, for example Add the image plugin. Keep the branch main. Do not create a new branch. Then select Commit changes again.

Step 2. Create eleventy.config.js. This file tells Eleventy to use the plugin, and how.

  1. Go back to Code → Repository, at the root.
  2. Select the plus icon (+), then New file.
  3. In the file name field, type eleventy.config.js.
  4. Copy this content and paste it in the editor:

    import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"
    
    export default function (eleventyConfig) {
      eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
        formats: ["webp", "auto"],
        widths: [600, 1200, "auto"],
        htmlOptions: {
          imgAttributes: {
            sizes: "100vw",
            loading: "lazy",
            decoding: "async",
          },
        },
      })
    }
    
  5. Select Commit changes, write a message, keep the branch main, and select Commit changes again.

Step 3. Change build.json. This file lists the steps of the build. The new step, npm i, downloads the plugin before the build.

  1. In Code → Repository, select build.json.
  2. Select Edit, then Edit single file.
  3. Delete all the content of the file. Copy this content and paste it:

    [
      { "type": "sh", "value": "npm i" },
      { "type": "build" }
    ]
    
  4. Select Commit changes, write a message, keep the branch main, and select Commit changes again.

Step 4. Publish from Silex. Your commits on GitLab do not start the build. Go back to Silex and publish your website. At this moment, Silex also writes build.sh again, from your new build.json. A pipeline that you start by hand on GitLab does not do this, so publish from Silex. If Silex shows an error about build.json, or an error like is not valid JSON, check the text you pasted in step 3.

Step 5. Check the pipeline.

  1. On GitLab, in your project, select Build → Pipelines. The newest pipeline is at the top.
  2. Wait until its status is Passed. This time, the build takes a bit longer: it downloads the plugin first.
  3. If the status is Failed, select the pipeline, then the job named pages. Its log shows the error, near the end. See Troubleshooting below.

Step 6. See the result.

  1. Open your website. Its address is in Deploy → Pages.
  2. Open a page with images and display its source code: right-click on the page and choose to view the page source.
  3. Each image is now inside a <picture> element, and uses files of the /img/ folder, such as /img/kCGub5O_3U-600.webp.

What the plugin does with your images

What the build does with an image like <img src="/assets/photo.jpg">:

  • It writes new files in _site/img/: WebP and JPEG, 600px wide, 1200px wide, and at the original width. "auto" in formats keeps the original format, so a PNG gives PNG files. It never makes a file wider than the original image.
  • It replaces the <img> with a <picture> element that lists these files. The <img> inside keeps its id, class and alt, and gets width, height, srcset, sizes, loading="lazy" and decoding="async".
  • The original files are still copied to _site/assets/.
  • An image with a full address, such as https://…, for example an image from a CMS, is downloaded at each build, then changed in the same way. Its new files go at the root of _site/, not in _site/img/. If the build cannot download it, see The build fails because of an image.

Each width and each format makes one more file for each image. On a website with many images, the build takes longer: start with few widths and formats.

Check your layout

The <img> is now inside a <picture> element. If a style depends on the image being a direct child of its parent, for example in a flex or grid container, check the published page.

Settings for one image

You can change what the plugin does for one image, with an attribute on this image in Silex:

  1. Select the image.
  2. At the top of the right panel, open Settings (gear icon).
  3. In the Attributes section, select +. Type the name of the attribute, for example eleventy:widths, and confirm.
  4. In the field of the new attribute, type the value, for example 200,400.
  5. Publish.

These attributes work:

  • eleventy:widths with the value 200,400: makes only these widths, in pixels, for this image.
  • eleventy:formats with the value webp: makes only this format for this image.
  • eleventy:ignore with the value true: the plugin does not change this image.

Add another plugin

Every plugin uses the same three files. The documentation of the plugin gives two things: the name of its npm package, for package.json, and the lines for eleventy.config.js.

Feature npm package Notes
Optimized images @11ty/eleventy-img Official Eleventy plugin. Its HTML transform changes every <img> of your pages at build time. Example above.
Sitemap @quasibit/eleventy-plugin-sitemap The most used sitemap plugin for Eleventy on npm. Its last version, 2.2.0, is from September 2022.
RSS feed @11ty/eleventy-plugin-rss Official Eleventy plugin.
Syntax highlighting @11ty/eleventy-plugin-syntaxhighlight Official Eleventy plugin. Colors the code samples of your pages. Example below.

For the sitemap and the RSS feed, follow the setup in the plugin documentation.

You already have a package.json and an eleventy.config.js? Do not create a second one. Add the new plugin to the same files. For example, with the image plugin and the syntax highlighting plugin:

package.json:

{
  "type": "module",
  "dependencies": {
    "@11ty/eleventy-img": "^7.1.1",
    "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2"
  }
}

eleventy.config.js:

import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"

export default function (eleventyConfig) {
  eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
    formats: ["webp", "auto"],
    widths: [600, 1200, "auto"],
    htmlOptions: {
      imgAttributes: {
        sizes: "100vw",
        loading: "lazy",
        decoding: "async",
      },
    },
  })
  eleventyConfig.addPlugin(syntaxHighlight)
}

build.json does not change: one npm i step installs all the plugins of package.json. See Customize the build for the full build.json reference.

Three things to know:

  • The config file must be at the root of the repository, not in public/. A config file inside public/ is ignored, and your build fails when a page uses something the plugin should provide.
  • Silex never creates an npm i step for you. Without it, your package.json is not installed and the plugin is never loaded.
  • The name to use is eleventy.config.js. The old name .eleventy.js still works, and it wins if both files exist. Create only one of them.

Do not import @11ty/eleventy in your config file

Eleventy runs through npx, so it is not installed in your repository. A line like import { HtmlBasePlugin } from "@11ty/eleventy" stops the build with Cannot find package '@11ty/eleventy'. Import your own plugins only, the ones listed in your package.json.

Shortcodes

Shortcodes are template tags, read at build time. Eleventy renders every page as a Liquid template, so shortcodes work on every website, with or without a data source.

A shortcode calls a function, defined in your eleventy.config.js, and the build replaces the tag with what the function returns. Plugins often provide shortcodes: the syntaxhighlight plugin above gives you a highlight shortcode.

Place the block

In the editor, open the blocks panel and find the Shortcode block, marked {%, in the last group. Drag it into your page.

Select it, open the Element settings (gear icon), and fill the two fields:

  • Shortcode name: the name of the shortcode, for example highlight.
  • Shortcode attributes: the parameters, for example js or param1, "example param 2".

The block writes the tag for you. Empty, it writes a simple tag:

{% highlight js %}

With other blocks inside it, it writes a paired tag, and your content stays between the two tags:

{% highlight js %}
  ... your blocks ...
{% endhighlight %}

Define the shortcode

The build needs to know the shortcode. It comes either from a plugin you installed, or from your own eleventy.config.js:

export default function (eleventyConfig) {
  eleventyConfig.addShortcode("year", () => new Date().getFullYear())

  eleventyConfig.addPairedShortcode("callout", (content, type = "info") => {
    return `<div class="callout callout-${type}">${content}</div>`
  })
}

At publication

Silex publishes the page with the tag inside it, and the build replaces the tag with the result. If the shortcode is not defined anywhere, the build fails with tag "<name>" not found and nothing is deployed.

What you cannot customize

Silex owns several files and rewrites them at every publication. Changes you make to them are lost:

  • The published folder structure. Silex writes your pages, CSS and assets into public/.
  • The front matter at the top of each page, and the .11tydata.mjs files next to the pages.
  • build.sh, generated from your build.json.
  • The CI file (.gitlab-ci.yml and its equivalent on other platforms), which only runs sh build.sh.

What is yours: build.json, and any file you add at the root of the repository, such as package.json and eleventy.config.js.

Troubleshooting

The build fails with tag "..." not found

The shortcode name is not known by the build. Check the spelling in the Shortcode name field, and check that the shortcode is defined in your eleventy.config.js, or provided by a plugin you installed.

My plugin has no effect

Check the three points in Add a plugin: eleventy.config.js at the root of the repository, the plugin in package.json, and an npm i step before the build step in build.json. Publish again from Silex. Then open the job log on your hosting platform (GitLab: Build → Pipelines, then the pages job), or run sh build.sh in a clone of your repository to get the same build locally.

Silex shows an error about build.json when you publish

The text of build.json is not valid, often because of a copy and paste error: a missing comma or a missing bracket. Silex stops the publication before it sends anything, and shows the error in the Publish dialog. For example ... is not valid JSON, or build.json step 0 must be { "type": "build" } or { "type": "sh", "value": "..." }. Open build.json on GitLab, paste the content of step 3 again, commit, and publish again.

The build fails because of an image

With the image plugin, the build fails when it cannot read an image: a file that is missing from your website, or an image from another website that the build cannot download. In the job log, you see ENOENT: no such file or directory for a missing file, or Bad response for https://... for an image from another website.

Fix or remove this image in Silex. Or tell the plugin to skip the images it cannot read, with the failOnError: false option. Replace the content of eleventy.config.js with:

import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"

export default function (eleventyConfig) {
  eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
    failOnError: false,
    formats: ["webp", "auto"],
    widths: [600, 1200, "auto"],
    htmlOptions: {
      imgAttributes: {
        sizes: "100vw",
        loading: "lazy",
        decoding: "async",
      },
    },
  })
}

The build then keeps these images as they are, and optimizes the other images.

See also

Edit this page on GitLab