Skip to content

Build awesome plugins

Build awesome (powered by Eleventy) runs at build time when you publish your site. Plugins extend what the build can do — optimize images, generate sitemaps, add search, and more.

Two things to remember:

  • Plugins run during the build, not in the editor. You won't see their effects until you publish.
  • You control the build pipeline. Once you customize it, Silex stops overwriting your configuration.

How the build works

When you click Publish, this happens:

  1. Silex generates your site files (HTML, CSS, assets)
  2. Files are committed to your GitLab repository
  3. The .gitlab-ci.yml file triggers a CI/CD pipeline
  4. Build awesome processes the files — applying plugins, optimizing assets
  5. The result is deployed to GitLab Pages

The default .gitlab-ci.yml looks like this:

# silexOverwrite: true
image: node:20
pages:
  stage: deploy
  environment: production
  script:
    - npx @11ty/eleventy@v3.0.0-alpha.20 --input=public --output=_site
    - mkdir -p public/css public/assets && cp -R public/css public/assets _site/
    - rm -rf public && mv _site public
    - echo "The site will be deployed to $CI_PAGES_URL"
  artifacts:
    paths:
      - public
  rules:
    - if: '$CI_COMMIT_TAG'

The silexOverwrite flag

The first line — # silexOverwrite: true — controls whether Silex overwrites this file each time you publish.

  • true (default): Silex replaces the file on every publish. Good when you don't need customization.
  • false: Silex leaves your file alone. Required when adding plugins.

Change it to false before customizing anything, or your changes will be lost on next publish.

Adding a plugin: step by step

Let's walk through adding a plugin using image optimization as the example.

Step 1: Create a package.json

In your GitLab repository (at the root, next to .gitlab-ci.yml), create a package.json:

{
  "dependencies": {
    "@11ty/eleventy-img": "^1.0.0"
  }
}

Step 2: Create an eleventy.config.js

At the same level, create eleventy.config.js:

const Image = require("@11ty/eleventy-img");

module.exports = function (eleventyConfig) {
  eleventyConfig.addShortcode("image", async function (src, alt, widths = [300, 600], sizes = "100vh") {
    let metadata = await Image(src, {
      widths,
      formats: ["avif", "jpeg"],
    });

    let imageAttributes = {
      alt,
      sizes,
      loading: "lazy",
      decoding: "async",
    };

    return Image.generateHTML(metadata, imageAttributes);
  });
};

This generates avif and jpeg versions of your images at 300px and 600px widths.

Step 3: Update .gitlab-ci.yml

Set silexOverwrite to false and add npm i before the build command:

# silexOverwrite: false
image: node:20
pages:
  stage: deploy
  environment: production
  script:
    - npm i
    - npx @11ty/eleventy@v3.0.0-alpha.20 --input=public --output=_site
    - mkdir -p public/css public/assets && cp -R public/css public/assets _site/
    - rm -rf public && mv _site public
    - echo "The site will be deployed to $CI_PAGES_URL"
  artifacts:
    paths:
      - public
  rules:
    - if: '$CI_COMMIT_TAG'

The key change: npm i installs the dependencies from your package.json before the build runs.

Image optimization with @11ty/eleventy-img

This is the most useful plugin for most sites. It transforms your images at build time to serve the smallest possible file to each visitor.

What it does

  • Generates multiple formats: avif, webp, jpeg, png, svg, gif
  • Generates multiple sizes from a single source image
  • Never upscales beyond the original dimensions
  • Adds proper width and height attributes to reduce layout shift
  • Fetches and caches remote images locally

Instead of using shortcodes, you can let the plugin process all <img> tags automatically:

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

export default function (eleventyConfig) {
  eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
    formats: ["avif", "webp", "jpeg"],
    widths: ["auto"],
    htmlOptions: {
      imgAttributes: {
        loading: "lazy",
        decoding: "async",
      },
    },
  });
};

This is the simplest approach for Silex sites — every image you add in the editor gets optimized automatically during the build.

Per-image overrides

You can control optimization per image using HTML attributes (in the Element settings (gear icon)):

  • eleventy:widths="200,600" — generate specific widths
  • eleventy:formats="webp" — use specific formats only
  • eleventy:ignore — skip this image entirely

Build performance tips

Image optimization adds build time. To keep builds fast:

  1. Limit formats. avif produces the smallest files but is the slowest to generate. Start with ["webp", "jpeg"] and add avif only if you need it.
  2. Use "auto" for widths unless you know you need specific sizes.
  3. Cache remote images. If your images come from a CMS, preserve the .cache folder between builds to avoid re-fetching.

Other useful plugins

Adds full-text search to your published site. Users can search across all pages without a server.

Sitemap

Generates an XML sitemap (sitemap.xml) that search engines use to discover your pages. Essential for SEO.

Pagination / Pagebreak

Splits long content across multiple physical pages with prev/next navigation. Different from collection pages, which generate one page per data item.

RSS

Generates an RSS feed so visitors can subscribe to your content. Useful for blogs.

eleventy-plugin-concat

A Silex Labs plugin that concatenates multiple CSS and JavaScript files into single files, reducing HTTP requests.

Common mistakes

  • Forgetting to set silexOverwrite to false. Your customizations get overwritten on next publish.
  • Forgetting npm i in the CI script. Without it, your package.json dependencies are not installed and the build uses no plugins.
  • Adding too many image formats. Each format multiplied by each width multiplied by each image adds up. Start small.
  • Not testing the build. After changing the CI file, publish and check the pipeline in GitLab (CI/CD → Pipelines) to see if it succeeds.

Learn more


Quiz

Q1: You customized .gitlab-ci.yml to add a plugin, but after publishing it went back to the default. What happened?

  • A) The plugin was not compatible
  • B) silexOverwrite was still set to true
  • C) You forgot to run npm i
Answer

B) silexOverwrite was still set to true — Silex overwrites the CI file on each publish when this flag is true. Set it to false before customizing.

Q2: You want all images on your site optimized automatically without changing your Silex design. Which approach should you use?

  • A) The shortcode approach — add shortcodes to each image
  • B) The HTML transform approach — it processes all img tags automatically
  • C) Manually optimize images before uploading
Answer

B) The HTML transform approach — it automatically processes every <img> tag in the build output. No changes needed in the editor.

Q3: Your build is slow. You're generating avif, webp, jpeg, and png for 5 different widths. What should you try first?

  • A) Reduce the number of formats — drop avif and png
  • B) Add more build minutes to GitLab
  • C) Use smaller source images
Answer

A) Reduce the number of formats — avif is the slowest to generate. Start with webp + jpeg and only add avif if you need the extra compression.

Q4: What file do you need to create to add plugin dependencies?

  • A) plugins.json
  • B) package.json
  • C) .eleventy.js
Answer

B) package.json — this is the standard Node.js dependency file. The CI script runs npm i to install the packages listed in it.

Q5: What's the difference between the Pagebreak plugin and collection pages?

  • A) No difference, they do the same thing
  • B) Pagebreak splits one design across multiple pages; collection pages generate one page per data item
  • C) Collection pages are for blogs, Pagebreak is for e-commerce
Answer

B) Pagebreak splits one design across multiple pages; collection pages generate one page per data item — they serve different purposes. Pagebreak is for long content, collection pages are for dynamic data.

Edit this page on GitLab