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, 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.

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-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>

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.


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

You may also like

  • Hi, i can’t have custom icons working.
    The first error i have is when i add

    @import “../theme/icons”;

    i got this

    so i must write

    @import “../theme/icons.scss”;

    After that the custom icons still not appear

    • Francesco Mussi

      Check the github repo to see if you have done it all correctly

    • Could you check the following repo and see if you missed anything?

      If that’s not the case, push a repo on your github and I’ll gladly help you 😀

    • Dieter Woestemeier

      Maybe you haven’t replaced the ai- prefix in the function makeIcon…

  • Francesco Mussi

    Great tutorial!
    I am having an headache trying to style the custom inside an ion-list.
    I don’t know why – but it has by default a strange positioning inside the list.
    Will try to figure it out

    • Hey @francesco_mussi37:disqus , thanks for trying this out. It may happen because all default ion-icons have the same proportion and are all square sized. When using custom icons, you also have to make sure they are all square and proportional. Of course you can use different shaped icons, but then it’s up to you to adjust the stylings accordingly.

      If that wasn’t the case, feel free to push a sample repo on github then paste the link here, I’ll gladly help you 🙂


      • Francesco Mussi

        Thanks for replying.
        Yes, that was exactly the reason. Different proportions. I managed anyway with some custom style, thanks!

  • Jeronimo Nascimento

    Great tutorial, it helps a lot!

    • My pleasure, I’m really glad it was useful for you!

  • Sukumar Dhoni

    simple and clear. Thanks!

  • Jose Pena

    Hello, this is exactly what I needed, but with Font Awesome. I was able to make it work based on your work and can now use Font Awesome icons as if they were Ionic icons. Thank you lots.

  • Best tutorial out there for adding custom icons.
    Cheers man, I owe you a pint!