How to use custom icons on Ionic 3

How to use custom icons on Ionic 3


One of the trending topics I see in the Ionic community is the usage of custom icons in an application. There are already awesome icons built in with Ionic 3, but sometimes you just want to make your application look more unique, or perhaps a designer gave you a set of image icons and you don’t know the best approach to use them. In that case, I highly recommend you to create your own font using SVG icons. This way, regardless of the icon size, it will look perfectly sharp in any device.

Today, I’ll be showing you the exact steps to integrate your custom icons and the ion-icon element.

This tutorial is inspired in this stack overflow topic.

Getting the icons

First of all, you’ve got to get your SVG icons. If you already have your icons or don’t want to pick icons manually, you can skip this step.
I’m no designer, so I use icons made by others. There’s an amazing platform called The Noun Project, which contains thousands of icons of every type and category you could think of. Really, you can search basically anything and you’ll find fantastic stuff. The icons are all free with creative commons, so we can create an entire set from there. In this example, we’ll be using just a few, for testing purposes.

 

Generating our new font
After downloading the desired icons, we are going to use an app called Icon Moon, which basically can turn a set of SVG icons into a font that a browser can easily understand. This app already has a few sets of icons (most of which are free), so if you haven’t picked your SVGs from somewhere else, you can get from there (you can browse its icon library).

Ok, the first thing we’ll do is import our SVGs:

 

Right after, we select which icons we want in our font and click on FONT:

 

 

Then we’ll get to a screen where it shows the icons configuration:

The icon names will be the name of our svg files. I like to have a way to distinguish between custom and default stuff, so the icons will all have a prefix of ai-(amazing icons). In this screen we can change the icon names, and also their content code. After setting everything up, we press the Download button at the right bottom corner and that’s it! The app will generate our webfont with all those nice icons.

Getting the css ready

After finishing downloading iconmoon.zip, open it up and you’ll see a bunch of files. What we want to use is style.css and the fonts folder, so ignore the rest. Add the font files to src/assets/fonts/, then rename the style.css file to icons.scss and add it under src/theme/.

Then, reference the newly created file on app.scss by adding this line: @import "../theme/icons"

Open up your recently added icons.scss.

First of all, add../assets/ to every path generated by iconmoon:
from: src: url('fonts/icomoon.eot?39m2i2');
to: src: url('../assets/fonts/icomoon.eot?39m2i2');

To make our icons work the same way as ion-icons, we have to add classes for device platforms (ios and android) just like ion-icon does. We have to do so because the ion-icon component renders the inside elements with dynamic classes generated depending on the platform the user is on, so we have to cover all cases. In case you want it for windows phone too, add the .ion-wp prefix as well.

Here I’m using an example for ai-pacman and ai-rock:

.ai-pacman:before ,
.ion-ios-ai-pacman:before ,
.ion-ios-ai-pacman-outline:before ,
.ion-md-ai-pacman:before ,
.ion-md-ai-pacman-outline:before  {
  content: '\e916';
  font-size: 26px;
}


.ai-rock:before ,
.ion-ios-ai-rock:before ,
.ion-ios-ai-rock-outline:before ,
.ion-md-ai-rock:before ,
.ion-md-ai-rock-outline:before  {
  content: '\e905';
  font-size: 26px;
}

Did you notice how poluted this gets? For each and every icon, we had to add 8 lines of code. I wonder how many lines we would have to write for over 30-50 icons.. Nah, too much work.

Fortunately, by using SASS we can create something called mixin. Mixins work similar to functions in javascript, in a way that we can define something that receives a set of arguments and outputs some css code. This way we can eliminate all our effort by creating a mixin that automates the process for us:

@mixin makeIcon($arg, $val) {
  .ai-#{$arg}:before ,
  .ion-ios-ai-#{$arg}:before ,
  .ion-ios-ai-#{$arg}-outline:before ,
  .ion-md-ai-#{$arg}:before ,
  .ion-md-ai-#{$arg}-outline:before  {
    content: $val;
    font-size: 26px;
  }
}

Now we only have to write a single line of code for each icon:

@include makeIcon(ai-rock, '\e905');
@include makeIcon(ai-pacman, '\e916');

Still.. refactoring the css to use the mixin is quite an effort. As I like to automate stuff, I use the tools in my favor. I created a find-replace regex to do that job for us (replace ai for whatever prefix you are using):

find: \.ai-([\S]*):before {\n\s*content: "(.*?)";\n}
replace: @include makeIcon($1, '$2');

With that you can do a find replace from your editor and get from this:

To this:

ps: For some reason that regex doesn’t work on Visual Studio Code. I still don’t know why.

PLEASE READ THIS CAREFULLY, OTHERWISE ION-ICONS WILL BREAK:

For some reason which I’m still trying to figure out, if we try running the project now, all custom icons will work, but Ionic’s default icons will break. What we have to do to fix this is go to variables.scss and change the line that has @import "ionic.ionicons"; to @import "ionicons";:

// In order to make custom icons work and not break ionic icons, change ionic.ionicons to ionicons
// @import "ionic.ionicons";
@import "ionicons";

We are done! Now our project is fully capable of using either Ionic default icons or our custom icons! The usage is the same, we just need to use our custom icons names such as:

<!--Using with ion-icon-->
<ion-icon name="ai-pacman"></ion-icon>

<!--Using with ion-tabs-->
<ion-tabs>
  <ion-tab [root]="tab1Root" tabTitle="Default icon" tabIcon="home"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Custom icon"  tabIcon="ai-pacman"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Custom icon"  tabIcon="ai-whatsapp"></ion-tab>
</ion-tabs>

And here’s the result:

 

That’s it! I hope you guys find this tutorial useful, and please let me know in case of any questions.

You can access a repository with the whole project here.

yannbraga

Web and mobile developer. Occasionally do some origami on spare time :)

You may also like