Home | Send Feedback

Integrate FontAwesome icons in an Angular application

Published: February 15, 2019  •  Updated: August 21, 2019  •  javascript, ionic4

When you bootstrap an Ionic 4 application with the Ionic CLI, you automatically have access to the Ionicons library. A collection of SVG icons for web, iOS, and Android development. The library is not that big, and you usually end up adding icons from other sources to your project. In my previous blog post, I showed you how to add individual SVG icons to an Ionic project.

In this blog post, we are going to look at another icon library, FontAwesome, and how to add it to your Ionic application. FontAwesome is a popular icon library and provides over 1500 icons for free. For $60 a year you get additional access to more than 3500 icons, total over 5000 icons.

FontAwesome provides free open source libraries for a variety of JavaScript front end frameworks, like Vue.js, React, Angular, Ember and more. In this blog post, I'm focusing on the Angular library.

Setup

To add FontAwesome to your project, you have to install the core library, one or more icon libraries and lastly the Angular integration library.

npm install @fortawesome/fontawesome-svg-core

npm install @fortawesome/free-brands-svg-icons
npm install @fortawesome/free-regular-svg-icons
npm install @fortawesome/free-solid-svg-icons

npm install @fortawesome/angular-fontawesome

The free version of FontAwesome gives your project access to a subset of icons. You only have access to the libraries above (brands, regular, solid). Visit the gallery to see which icons are free and which are part of the pro version.

If you want to use icons from the pro set, you first have to buy a license and then configure the npm repository:

Globally

npm config set "@fortawesome:registry" https://npm.fontawesome.com/ && \
 npm config set "//npm.fontawesome.com/:_authToken" TOKEN

Locally on a per-project basis

Create a file .npmrc in the root of your project and add the following code

@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=TOKEN

After that, install the icons from the pro version

npm install @fortawesome/pro-solid-svg-icons
npm install @fortawesome/pro-regular-svg-icons
npm install @fortawesome/pro-light-svg-icons

Usage

The Angular FontAwesome library provides two ways to import icons into your application.

Explicit reference

In this mode, you import the icons in the component TypeScript code, create an instance variable and reference this variable from the template.

First, import the FontAwesome module into your module file.

[https://github.com/ralscha/blog2019/blob/master/fa/src/app/app.module.ts#L8]

Add the module to the import sections.

[https://github.com/ralscha/blog2019/blob/master/fa/src/app/app.module.ts#L30-L31]

Import the icons you want to use in your template and create an instance variable.

import {faHandPointLeft, faHandPointRight} from '@fortawesome/free-regular-svg-icons';

@Component({
  selector: 'app-home',
  templateUrl: './home.page.html',
  styleUrls: ['./home.page.scss']
})
export class HomePage implements OnInit, OnDestroy {
  faHandPointLeft = faHandPointLeft;
  faHandPointRight = faHandPointRight;

home.page.ts

Reference the instance variables from the fa-icon component with the [icon] directive

  <ion-button>
    <fa-icon slot="start" [icon]="faHandPointLeft"></fa-icon>
    Left Icon
  </ion-button>

  <ion-button>
    Right Icon
    <fa-icon slot="end" [icon]="faHandPointRight"></fa-icon>
  </ion-button>

home.page.html

component usage


Library

The previous approach works fine if you need to reference an icon just from one component. As soon as you start using icons in multiple components, this approach is not that convenient.

Instead of registering the icons per component, you can add them to a library in your module file. This way, all these icons are available to any other component. The downside is that the icons are managed separately from the component. If somebody accidentally deletes an icon from the library, a component that references this icon could break.

Like in the previous approach, import FontAwesomeModule and in addition FaIconLibrary.

import {FaIconLibrary, FontAwesomeModule} from '@fortawesome/angular-fontawesome';

app.module.ts

@NgModule({
  declarations: [AppComponent, HomePage],
  entryComponents: [],
  imports: [BrowserModule,
    FontAwesomeModule,

app.module.ts

In the same module file import the icons you need for your application. Either each icon individually or the complete icon set.

import {
  faAsterisk, faBell as faSolidBell, faCircle, faCloud,
  faCog, faEnvelopeOpen, faHandPointLeft, faMobile, faMoon,
  faPlay, faSkating, faSkiing, faSkiingNordic,
  faSmileBeam as faSmileBeanSolid, faSmileWink as faSmileWinkSolid,
  faSnowboarding, faSpinner, faSquare, faStar, faSun,
  faSwimmer, faSync, faBan, faCamera
} from '@fortawesome/free-solid-svg-icons';
import {faBell as faRegularBell, faSmileBeam, faSmileWink} from '@fortawesome/free-regular-svg-icons';
// import {fas} from '@fortawesome/free-solid-svg-icons';

app.module.ts

In the constructor, inject the FaIconLibrary and add the icons to the library with addIconPacks() or addIcons.

export class AppModule {
  constructor(library: FaIconLibrary) {
    // library.addIconPacks(fas);
    library.addIcons(faSmileWinkSolid, faSmileBeanSolid,
      faSmileWink, faSmileBeam, faEnvelopeOpen, faCloud,
      faMobile, faSquare, faSpinner, faCircle,
      faSync, faPlay, faSun, faMoon, faStar,
      faHandPointLeft, faAsterisk, faCog, faSkating,
      faSkiing, faSkiingNordic, faSnowboarding, faSwimmer,
      faSolidBell, faRegularBell, faCamera, faBan);
  }
}

app.module.ts

Note that importing a complete icon pack significantly increases the size of your application bundle.

In the components, you access these icons by name. Notice that the name is not the same as the name from the import statement. You can derive the name by removing the fa prefix and replacing camelCase with dashes. For example: faSmileWink becomes smile-wink
The gallery page also tells you the name.

    <fa-icon icon="smile-wink"></fa-icon>
    <fa-icon icon="smile-beam"></fa-icon>

home.page.html

By default, specifying only the name references the icons from the solid library (fas). To reference icons from other libraries you have to specify the prefix

    <fa-icon [icon]="['far', 'smile-wink']"></fa-icon>
    <fa-icon [icon]="['far', 'smile-beam']"></fa-icon>

home.page.html

usage

Supported prefixes:

You may change the default prefix (fas), if you have to reference more icons from a different icon set than the default fas. To change the default, inject FaConfig into the constructor and assign the new default to the defaultPrefix property.

import { FaConfig } from '@fortawesome/angular-fontawesome';
export class AppComponent {
  constructor(faConfig: FaConfig) {
      faConfig.defaultPrefix = 'far';
  }
}

Features

The Angular FontAwesome library supports many options to transform and combine icons.

The following code shows you how to resize, rotate and flip icons

    <fa-icon [icon]="['fas', 'skiing']" size="lg"></fa-icon>
    <fa-icon [icon]="['fas', 'skiing']" size="2x"></fa-icon>
    <fa-icon [icon]="['fas', 'skiing']" size="3x"></fa-icon>
    <fa-icon [icon]="['fas', 'skiing']" size="4x"></fa-icon>

home.page.html

    <fa-icon [icon]="['fas', 'snowboarding']" size="3x"></fa-icon>
    <fa-icon [icon]="['fas', 'snowboarding']" size="3x" rotate="90"></fa-icon>
    <fa-icon [icon]="['fas', 'snowboarding']" size="3x" rotate="180"></fa-icon>
    <fa-icon [icon]="['fas', 'snowboarding']" size="3x" rotate="270"></fa-icon>

home.page.html

    <fa-icon [icon]="['fas', 'swimmer']" size="3x" flip="horizontal"></fa-icon>
    <fa-icon [icon]="['fas', 'swimmer']" size="3x" flip="vertical"></fa-icon>
    <fa-icon [icon]="['fas', 'swimmer']" size="3x" flip="both"></fa-icon>

home.page.html

resize

It's also easy to add bindings to any directive and dynamically do transformations.

    <fa-icon size="5x" [icon]="['fas', 'hand-point-left']" transform="rotate-{{magicLevel}}"></fa-icon>
    <input type='range' min="0" max="360" [value]="magicLevel" (input)="magicLevel=$event.target.value"/>

home.page.html

transform


If you need to align a bunch of icons vertically, you can set the directive fixedWidth to true, and the library enforces that all icons have the same width.

    <ul>
      <li>
        <fa-icon [icon]="['fas', 'swimmer']" [fixedWidth]="true" size="2x"></fa-icon>
        Swimmer
      </li>
      <li>
        <fa-icon [icon]="['fas', 'snowboarding']" [fixedWidth]="true" size="2x"></fa-icon>
        Snowboarding
      </li>
      <li>
        <fa-icon [icon]="['fas', 'skiing']" [fixedWidth]="true" size="2x"></fa-icon>
        Skiing
      </li>
      <li>
        <fa-icon [icon]="['fas', 'skiing-nordic']" [fixedWidth]="true" size="2x"></fa-icon>
        Skiing Nordic
      </li>
    </ul>

home.page.html

The following picture shows you the difference. The first 4 icons use their normal width. The other 4 icons have their width aligned with fixedWidth.

fixedWidth


The library also supports a spin and pulse animation. These work especially well with icons from the spinners category

    <fa-icon [icon]="['fas', 'asterisk']" size="6x" [spin]="true"></fa-icon>
    <fa-icon [icon]="['fas', 'cog']" size="6x" [pulse]="true"></fa-icon>

home.page.html

    <fa-icon size="6x" [icon]="['fas', 'sync']" [spin]="syncRunning"></fa-icon>
    <ion-button (click)="syncRunning = true" [disabled]="syncRunning">Start</ion-button>
    <ion-button (click)="syncRunning = false" [disabled]="!syncRunning">Stop</ion-button>

home.page.html

animation


The border directive draws a border around the icon. If you need to wrap text around icons, the pull directive helps with that use case.

  <ion-card>
    <ion-card-content>
      <fa-icon [icon]="['fas', 'asterisk']" [border]="true" size="2x" pull="left"></fa-icon>
      Lorem ipsum dolor sit amet, ei cum possit denique, debet mundi sit ne.
    </ion-card-content>
  </ion-card>

  <ion-card>
    <ion-card-content>
      <fa-icon [icon]="['fas', 'asterisk']" [border]="true" size="2x" pull="right"></fa-icon>
      Lorem ipsum dolor sit amet, ei cum possit denique, debet mundi sit ne.
    </ion-card-content>
  </ion-card>

home.page.html

borderpull


With Mask, an application can combine two icons and create one single-color shape.
Transform allows you to scale, position, flip, and rotate icons arbitrarily.

    <fa-icon size="6x" [icon]="['fas', 'swimmer']" transform="shrink-10 down-4" [mask]="['fas', 'circle']"></fa-icon>

home.page.html

mask

Stacking allows you to easily stack multiple icons on top of each other.

    <fa-stack size="5x">
      <fa-icon [icon]="['fas', 'camera']" stackItemSize="1x"></fa-icon>
      <fa-icon [icon]="['fas', 'ban']" style="color:Tomato" stackItemSize="2x"></fa-icon>
    </fa-stack>

home.page.html

stacking

While stacking simply puts the icons on top of each other, layering gives you even more control how to place multiple icons and text on top of each other.

    <fa-layers size="6x">
      <fa-icon [icon]="['fas', 'play']" transform="rotate--90 grow-2"></fa-icon>
      <fa-icon [icon]="['fas', 'sun']" [inverse]="true" transform="shrink-10 up-2"></fa-icon>
      <fa-icon [icon]="['fas', 'moon']" [inverse]="true" transform="shrink-11 down-4.2 left-4"></fa-icon>
      <fa-icon [icon]="['fas', 'star']" [inverse]="true" transform="shrink-11 down-4.2 right-4"></fa-icon>
    </fa-layers>

home.page.html

layering

    <fa-layers size="5x">
      <fa-icon [icon]="['fas', 'cloud']"></fa-icon>
      <fa-layers-text content="Cloud" style="color: white;" transform="shrink-12"></fa-layers-text>
    </fa-layers>

home.page.html

layeringtext

    <fa-layers size="5x">
      <fa-icon [icon]="['fas', 'envelope-open']"></fa-icon>
      <fa-layers-counter content="5"></fa-layers-counter>
    </fa-layers>

home.page.html

layeringcounter


With the [styles] directive you can control all kind of properties of the SVG. This directive works similar to the [ngStyle] directive and allows you to dynamically bind properties from the TypeScript code.

    <fa-icon size="5x" [icon]="['fas', 'bell']" [styles]="dynamicStyle()"></fa-icon>
    <fa-icon size="5x" [icon]="['far', 'bell']"
             [styles]="{'color': color, 'stroke': stroke, 'stroke-width': strokeWidth + 'px', 'opacity': opacity}"></fa-icon>

home.page.html

  color = 'red';
  stroke = 'red';
  strokeWidth = 0;
  opacity = 1;

  private interval: number;

  ngOnDestroy(): void {
    clearInterval(this.interval);
  }

  ngOnInit(): void {
    this.interval = setInterval(() => {
      this.color = this.randomColor();
      this.stroke = this.randomColor();
      this.strokeWidth = this.randomWidth();
      this.opacity = Math.random();
    }, 1000);
  }

  dynamicStyle() {
    return {
      opacity: Math.random(),
      color: this.randomColor(),
      stroke: this.randomColor(),
      'stroke-width': this.randomWidth() + 'px'
    };
  }

  private randomWidth(): number {
    return Math.floor(Math.random() * 30) + 1;
  }

  private randomColor(): string {
    return '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
  }

home.page.ts

styles


This concludes this tutorial about FontAwesome and the Angular library. Visit the project page for more in-depth and up to date information.

The source code for the examples in this blog post is hosted on GitHub:
https://github.com/ralscha/blog2019/tree/master/fa