uncenter / eleventy-plugin-icons

✨ A plugin for Eleventy to add and transform icons from any icon set.
https://www.npmjs.com/package/eleventy-plugin-icons
MIT License
11 stars 0 forks source link
11ty eleventy icons

eleventy-plugin-icons

Eleventy

Add icons to your Eleventy site, made easy.

Turn an 11ty shortcode like this:

{% icon "star" %}

Into an SVG like this, right in your templates:

<svg class="icon icon-star" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>

You can change/set attributes for an icon right in the shortcode:

{% icon "star", stroke="#ed8a19", class="starry-night" %}

[!WARNING] Using keyword arguments as seen above might not be available in all template languages - all examples in this README are using Nunjucks, which supports kwargs. You can instead provide an attributes object as the second argument like this:

{% icon "star", { "stroke": "#ed8a19", "class": "starry-night" } %}

or even a JSON string of an object:

{% icon "star", '{ "stroke": "#ed8a19", "class": "starry-night" }' %}

You can set attributes for all icons:

{
  icon: {
    attributes: {
      width: "50",
      height: "50"
    },
  }
}

You can add any directory as a source for your icons, including icons from NPM packages (in node_modules, see Popular icon sets).

Install

npm i eleventy-plugin-icons
pnpm add eleventy-plugin-icons
yarn add eleventy-plugin-icons
bun add eleventy-plugin-icons

Usage

To enable this plugin, add the following to your 11ty configuration file.

const pluginIcons = require('eleventy-plugin-icons');

module.exports = (eleventyConfig) => {
  eleventyConfig.addPlugin(pluginIcons, {});
};

To give you an idea of the level of customization this plugin offers, take a look at the default configuration below. To start configuring right now, skip to Configuration.

[!NOTE] Future examples of options will just be an object, like the default options object below. To edit your options, edit the {} object from the line:

eleventyConfig.addPlugin(pluginIcons, {});
{
  mode: 'inline',
  sources: [],
  icon: {
    shortcode: 'icon',
    delimiter: ':',
    transform: async (content) => content,
    class: (name, source) => `icon icon-${name}`,
    id: (name, source) => `icon-${name}`,
    attributes: {},
    attributesBySource: {},
    overwriteExistingAttributes: true,
    errorNotFound: true,
  },
  sprite: {
    shortcode: 'spriteSheet',
    attributes: {
      class: 'sprite-sheet',
      'aria-hidden': 'true',
      xmlns: 'http://www.w3.org/2000/svg',
    },
    extraIcons: {
      all: false,
      sources: [],
      icons: [],
    },
    writeFile: false,
  },
}

Getting started

To start, you need a source to pull icons from. For example, if you have some custom icons in the src/icons directory, you can add those as a source like so:

{
  sources: [{ name: 'custom', path: './src/icons' }];
}

Now in your templates you can insert your icons using the icon shortcode.

{% icon "custom:my-icon" %}

As you can see, the icon "identifier" or name must be prefixed by the name of the source. However, you can make a source the default source with default: true. With a default source, icons can be inserted without an indentifier ({% icon "my-icon" %} instead of {% icon "custom:my-icon" %}).

{
  sources: [{ name: 'custom', path: './src/icons', default: true }];
}

You can add as many sources as you want, but you can only have one default source.

Popular icon sets

Often you will want to use your favorite icon set; since you can use icons from any folder, we can pull them from the node_modules folder. There are no sources defined out of the box, but here are some popular icon sets for reference:

Package Icons Directory
Simple Icons simple-icons node_modules/simple-icons/icons
Lucide lucide-static node_modules/lucide-static/icons
Tabler @tabler/icons node_modules/@tabler/icons/icons
Feather feather-icons node_modules/feather-icons/dist/icons

To use icons from a package, install the package and define the source in sources. For example, to use a source named lucide that points to the icons in node_modules/lucide-static/icons:

npm i lucide-static
{
  sources: [{ name: 'lucide', path: 'node_modules/lucide-static/icons' }],
}

Configuration

mode

The mode option specifies how icons are handled. It can take one of two values:

[!IMPORTANT] Adding attributes on a per-icon basis that affect the appearance of the icon (e.g. fill or stroke) in sprite mode will not function correctly due to the limitations of SVG sprites.

sources

The sources option is an array of source objects, each of which has the following properties:

You can add multiple sources to categorize and organize your icons.

{ name: 'custom', path: './src/icons', default: true }

[!NOTE] You can refer to Getting started for more information on adding sources.

icon

This section outlines various options related to the icon shortcode.

shortcode

The shortcode option specifies the name of the shortcode used to insert icons. For example, if you set shortcode to 'insertIcon', you would use {% insertIcon %} to insert an icon.

delimiter

The delimiter option defines the character used to separate the source and icon name in the shortcode. For example, if the delimiter is set to '@', you would use custom@my-icon to reference an icon from the custom source.

transform

The transform option is an asynchronous function that allows you to modify the raw content of an SVG before attribute manipulation. By default, it simply returns the original content. You can customize this function to perform transformations as needed.

For example, you could optimize each icon with SVGO:

const { optimize, loadConfig } = require('svgo');

const pluginIcons = require('eleventy-plugin-icons');

module.exports = (eleventyConfig) => {
  eleventyConfig.addPlugin(pluginIcons, {
    // ...
    icon: {
      transform: async (svg) => {
        try {
          const config = await loadConfig('./svgo.config.js');
          try {
            const result = optimize(svg, config);
            return result.data;
          } catch (error) {
            throw new Error('Error optimizing content with SVGO.');
          }
        } catch (error) {
          throw new Error('Error loading SVGO config file.');
        }
    }
  });
};

class

The class option adds a dynamically generated class to the class attribute of the inserted icon. The function takes the icon name and source as arguments and should return a string. By default, it generates a class like icon icon-my-icon.

id

The id option defines the dynamic id attribute for sprite icons and the href attribute for sprite references. This function takes the icon name and source as arguments and should return a string. By default, it generates an ID like icon-my-icon.

attributes

The attributes option allows you to set additional (static) attributes for the icon. It takes an object where keys represent attribute names, and values represent attribute values. For example, { 'aria-hidden': 'true' } sets aria-hidden="true".

attributesBySource

The attributesBySource option allows you to set icon attributes based on their source. It takes an object where each key represents a source name, and the corresponding value is another object specifying attribute-value pairs. For example, { custom: { 'aria-hidden': 'true' } } sets aria-hidden="true" if the source is custom.

overwriteExistingAttributes

The overwriteExistingAttributes option determines whether existing attributes on the original SVG should be overwritten. When set to true, existing attributes will be replaced with the new attributes. If set to false, existing attributes will be merged with new ones.

errorNotFound

The errorNotFound option controls error handling for icons that are not found. When set to true, an error will be thrown for missing icons. If set to false, only a warning will be displayed.

sprite

This section outlines options related to the sprite shortcode.

shortcode

The shortcode option specifies the name of the shortcode used to insert the sprite sheet. For example, if you set shortcode to 'insertSprite', you would use {% insertSprite %} to insert the sprite sheet. This shortcode takes no arguments and is used when mode is set to 'sprite'.

class

The class option defines the class attribute of the inserted sprite SVG.

attributes

The attributes option allows you to set additional attributes for the sprite SVG. It takes an object where keys represent attribute names, and values represent attribute values.

extraIcons

The extraIcons option lets you add additional icons to the sprite sheet, even if they are not directly used in your content. It has the following properties:

writeFile

The writeFile option controls whether the generated sprite SVG is written to a specified path in the 11ty output directory. If you want to write the sprite SVG to a file, provide a string representing the file path. To disable writing the file, set writeFile to false.

License

MIT