How to generate a webfont [automated setup]

All well known web icon sets are shipped in format of fonts. For example it is Fontawesome webfont which ships in woff2 / eot / ttf formats.

Here I will show how to craft such icon webfont from your custom svg icons. Delivering icons with webfont allows loading them in the most efficient way and ensure text remains visible during webfont load.

This method works for any npm-based project (e.g. SPAs like React, Vue.js etc). Idea is next:

  1. Collect some svg files into one folder in the project, for example exported from Figma or vector graphics editor
  2. Create a npm script which will generate ttf / woff / eot fonts + CSS file which will import and connect them
  3. Then you will need just connect/import CSS file into your app
  4. Every time when you change or add an icon, you need only rerun npm script

Some times ago before 2017 there was a great package called webfonts-generator which generated webfont using another library [email protected]. But maintener stopped work on webfonts-generator, when svgicons2svgfont got several great updates and fixes (up to 9.x.x) – most important fix of messed look of icons after webfont generation. So we've found a new fork vusion-webfonts-generator using this method and we will explain how to integrate it into your app.

First, install it into your app:

npm i vusion-webfonts-generator

Now create script generate_font.js which will run the generator:

const webfontsGenerator = require('vusion-webfonts-generator');
const fs = require('fs');

fs.readdir('res/font', function(err, items) {
  if (err) {
    console.log('cant read res directory');
  }
  const files = items.filter((i) => i.toLowerCase().endsWith('.svg')).map(
    (i) => 'res/font/'+i);

  webfontsGenerator({
    files: files,
    dest: 'css/icons',
    fontName: 'ptroiconfont',
    
    // https://github.com/nfroidure/svgicons2svgfont options
    normalize: true,
    
    cssTemplate: 'res/font/font-css.hbs',
    templateOptions: {
      classPrefix: 'my-icon-',
      baseSelector: '.my-icon'
    },
    types: ['svg', 'ttf', 'woff', 'eot']
  }, function (error) {
    if (error) {
      console.log('Fail!', error);
    } else {
      console.log('Done!');
    }
  })
})

Now place icons to res/font/ folder.

Also create a file res/font/font-css.hbs (This is template for CSS file which will hold needed styles):

@font-face {
	font-family: "{{fontName}}";
	src: {{{src}}};
	font-weight: normal;
    font-style: normal;
}

{{baseSelector}} {
}

{{baseSelector}}:before {
	font-family: {{fontName}} !important;
	font-style: normal !important;
	font-weight: normal !important;
	font-variant: normal !important;
	text-transform: none !important;
	speak: none;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

{{#each codepoints}}
.{{../classPrefix}}{{@key}}:before {
	content: "\\{{this}}";
}
{{/each}}

Add script to package.json scripts section:

"scripts": {
    "buildfont": "node generate_font.js"
},

And run it now and every time when you will change icons:

npm run buildfont

Include generated css file into your app and make sure it loads font files correctly (using Devtools ➡ Network).

To use icons in HTML or your SPA templates (Vue.js, React), add this:

<i class="my-icon my-icon-apply"></i>

Image for a hint

#webfont #css #svg #react #vuejs
menu 12
Bruce Hardy profile picture
Oct 25, 2020
by Bruce Hardy

Best related

Other by Bruce Hardy