Adding Custom Icons

Custom icons can be added as standalone SVG files, SVG sprites, or icon fonts.

Choosing a Format

Format Best suited for Characteristics

Standalone SVG files

A small number of custom icons

Each icon is stored in a separate file. The browser loads only the icons used in the UI.

SVG sprite

A collection of custom icons

Multiple icons are stored as symbols in one file and selected by their identifiers.

Icon font

An existing font-based icon library

Requires font files and CSS configuration. Icons are selected using CSS classes, ligatures, or character codes.

For information about placing icons using attributes, nested elements, or Java, see Using Icons.

Standalone SVG Files

SVG files can be added to your static content directory. By default, Spring Boot serves static resources from the following locations in the classpath: /static, /public, /resources, or /META-INF/resources. To organize icons, you can use a subfolder such as META-INF/resources/icons.

To display an SVG file, use the svgIcon component:

<svgIcon resource="/icons/tree.svg"/>

You can also create an SVG icon programmatically:

SvgIcon treeIcon = new SvgIcon();
treeIcon.setSrc(DownloadHandler.forClassResource(
        getClass(),
        "/META-INF/resources/icons/tree.svg",
        "tree.svg"
));
standaloneIconButton.setIcon(treeIcon);

SVG Sprites

An SVG sprite is a collection of images stored as symbols in a single SVG file. Each symbol has an identifier that is used to select the corresponding icon.

To add an SVG sprite:

  1. Create a JavaScript file for your icon set in the /frontend/icons/ directory. The following code defines a sprite containing three icons:

    my-icons.js
    import '@vaadin/icon/vaadin-iconset.js';
    
    const template = document.createElement('template');
    
    template.innerHTML = `<vaadin-iconset name="my-icons" size="24">
      <svg><defs>
        <g id="star"><path d="M12 .587l3.668 7.568 8.332 1.207-6 5.848 1.416 8.263L12 18.896l-7.416 3.895L6 14.162l-6-5.848 8.332-1.207z" fill="#FFD700"/></g>
        <g id="heart"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" fill="#FF69B4"/></g>
        <g id="circle"><circle cx="12" cy="12" r="10" fill="#1E90FF"/></g>
      </defs></svg>
    </vaadin-iconset>`;
    
    document.head.appendChild(template.content);
  2. Create a Java enum that implements IconFactory and add the @JsModule annotation referring to the JavaScript file:

    MyIcons.java
    package com.company.onboarding.icons;
    
    import com.vaadin.flow.component.dependency.JsModule;
    import com.vaadin.flow.component.icon.Icon;
    import com.vaadin.flow.component.icon.IconFactory;
    import java.util.Locale;
    
    @JsModule("./icons/my-icons.js")
    public enum MyIcons implements IconFactory {
        STAR,
        HEART,
        CIRCLE;
    
        public Icon create() {
            return new Icon("my-icons",
                    name().toLowerCase(Locale.ENGLISH).replace('_', '-'));
        }
    }

After the icon set is registered, reference an icon using the icon-set name and symbol identifier:

<icon icon="my-icons:star"/>
<icon icon="my-icons:heart"/>
<icon icon="my-icons:circle"/>
sprite icons

Or create an icon programmatically:

spriteIconButton.setIcon(MyIcons.STAR.create());

Icon Fonts

An icon font is a collection of icons delivered as a font. Icons are rendered as characters from that font.

After you add a custom icon font you can use it to override the default application icons. See Overriding Default Icons for details.

To add an icon font, you will need the following:

  • One or more font files – commonly .woff2, with optional fallbacks such as .woff, .ttf, or .otf.

  • A global @font-face declaration – typically placed in a stylesheet that you import into your theme’s main stylesheet (styles.css).

  • Optionally, a stylesheet with icon CSS classes — often added alongside the @font-face declaration and also imported into styles.css.

Adding the Material Icons Font

This example shows how to add the Material Icons font to your application theme.

Using Local Font Files

To use Material Icons without an external service, create a material subdirectory in the active application theme directory.

Add the following files:

  • material-icons.woff2

  • material-icons.woff

  • material-icons.ttf

  • material-icons.css – includes the @font-face declaration and the CSS class for icons:

    material-icons.css
    @font-face {
      font-family: "Material Icons";
      font-style: normal;
      font-weight: 400;
      font-display: block;
      src:
        url("./material-icons.woff2") format("woff2"),
        url("./material-icons.woff") format("woff"),
        url("./material-icons.ttf") format("truetype");
    }
    .material-icons {
      font-family: "Material Icons";
      font-weight: normal;
      font-style: normal;
      font-size: 24px;
      line-height: 1;
      letter-spacing: normal;
      text-transform: none;
      display: inline-block;
      white-space: nowrap;
      word-wrap: normal;
      direction: ltr;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-rendering: optimizeLegibility;
      font-feature-settings: "liga";
    }

The browser uses the first font format it supports. Therefore, every font file declared in src must be downloaded and placed next to material-icons.css.

Import the stylesheet into the theme’s main stylesheet:

styles.css
@import url('material/material-icons.css');

Using Google Fonts

You can load Material Icons from Google Fonts instead of storing the font files in your application. This option requires users' browsers to have network access to Google Fonts.

Remove the import of material/material-icons.css from the theme’s styles.css, and add the following import instead:

styles.css
@import url("https://fonts.googleapis.com/css2?family=Material+Icons&display=swap");

The imported Google Fonts stylesheet provides the @font-face declaration and the CSS class for Material Icons, so no local font files or additional @font-face declaration are needed.

Using Font Icons

After configuring the font using either option, create an icon with the fontIcon component.

Depending on the font and its stylesheets, the fontIcon component can identify an icon in two ways:

  • A ligature, such as calendar, set with the ligature attribute. This requires a font that supports ligatures.

  • A hexadecimal character code, such as f199, set with the charCode attribute.

    The following example show these options:

    <fontIcon fontFamily="Material Icons" ligature="search"/>
    <fontIcon fontFamily="Material Icons" charCode="e8b6"/>