Skip to content

ionic 4 custom icons #589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chukwu opened this issue Aug 2, 2018 · 37 comments
Closed

ionic 4 custom icons #589

chukwu opened this issue Aug 2, 2018 · 37 comments
Labels
triage New issues

Comments

@chukwu
Copy link

chukwu commented Aug 2, 2018

Migrating from ionic 3 to ionic 4 doesn't look and feel as easy as the ionic team say.

  1. How do i add extra custom icons compatible to tabs, buttons and everything
<ion-icon name="my-custom-icon"></ion-icon>
<ion-tab label="Music" icon="my-custom-icon"></ion-tab>

Without a documentation or tutorial, migrating would be a waste of my time. Alot has changed and thus far, this seems to be the most painful

@peterennis
Copy link
Contributor

@chukwu
Look at this issue: ionic-team/ionic-framework#14857
Working demo here: https://aesvg.adaept.com/
Repo here: https://github.com/peterennis/ae-svg-components

Custom icons would also be svg.
Look in the iconicons repo here: https://github.com/ionic-team/ionicons

Here is an example of a custom icon: https://aetabs.adaept.com/tabs/(contact:contact)
Repo here: https://github.com/peterennis/aetabs/blob/master/src/app/pages/contact/contact.page.html

Documentation is behind the curve but being worked on by the ionic team 😄

@Awoshe
Copy link

Awoshe commented Aug 3, 2018

@peterennis
How do I add custom svg icons to the tabbar ?
in ionic 3 I did this:

$home-active: url(../assets/svg/homeactive.svg);
$home-inactive: url(../assets/svg/homeinactive.svg);

ion-icon {
      &[class*="aw-"] {
      mask-size: contain;
      mask-position: 50% 50%;
      mask-repeat: no-repeat;
      background: transparent;
      --ion-color-base: transparent !important;
     
    }

      &[class*="aw-home"] {
        mask-image: $home-inactive;
        .tab-button[aria-selected=true] & {
          mask-image: $home-active;
        }
     }

Now this does not work.

@peterennis

This comment has been minimized.

@ransoing
Copy link

You can slightly modify the build config to add new icons to the ionicons library, and use them anywhere.

  1. Create a new folder in your project to store your custom icons, i.e. src/assets/custom-ion-icons.
  2. Modify angular.json. Find this section:
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              }
            ],

See how it's packaging all the svg files from the ionic library into "./svg"? Those are the default icons. Whenever you use one of the default icons, your app finds it in that output directory. We can add our own icons to that directory. Add one more object to the "assets" array, so it looks like this:

            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "src/assets/custom-ion-icons",
                "output": "./svg"
              }
            ],
  1. Create your own icons and save them to your custom-ion-icons folder. For each new icon, create two files (one for iOS, one for android/material-design). The following would create a new icon named "newicon":
src/assets/custom-ion-icons/ios-newicon.svg
src/assets/custom-ion-icons/md-newicon.svg

The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

  1. Use your icon anywhere, using the name "newicon"!
<ion-icon name="newicon"></ion-icon>
<ion-tabs>
  <ion-tab label="your-tab-label" icon="newicon" href="/tabs/(home:home)">
    <ion-router-outlet name="your-outlet-name"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

@chukwu
Copy link
Author

chukwu commented Sep 1, 2018

@ransoing .... I'll try this. If it works, then I'm all set for migration. It actually looks easier this way than IONIC 3. The next big thing would be to modify my CSS nestings due to shadow DOM restrictions.

Thanks mate.

@ransoing
Copy link

ransoing commented Sep 1, 2018

Giving it a little bit more thought, it would be better to put your custom-ion-icons folder as a sibling to src, because otherwise your icons will be included twice in the final package.

@ransoing
Copy link

ransoing commented Sep 3, 2018

I've discovered that this may not work properly if your custom svg file defines any colors. The ionic framework overrides svg fill colors with CSS, and defining colors in the svg file may prevent ionic from setting colors properly.

@peterennis

This comment has been minimized.

@narcodico
Copy link

@ransoing Your approach is the most elegant, but for me it works on first load. As soon as I reload the app I get the GET http://localhost:8100/svg/ios-message.svg 404 (Not Found) error. I've set up a custom-ion-icons folder as sibling to src folder with an ios-message.svg and a md-message.svg.

angular.json:

"assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "custom-ion-icons",
                "output": "./svg"
              }
            ]

I guess you could always do something like <ion-icon src="/custom-ion-icons/ios-message.svg" slot="start"></ion-icon>, but is not that elegant of an approach.

Anyone any thoughts on why it only works on initial load ?
Thanks!

@ransoing
Copy link

ransoing commented Oct 8, 2018

@RollyPeres does it work properly if you put your custom-ion-icons inside your src folder? I wonder if there's something weird going on when it detects changes in src and recompiles.

@anyangdp
Copy link

anyangdp commented Dec 7, 2018

@narcodico
Copy link

@anyangdp will check it out. Nice!

@peterennis
Copy link
Contributor

@anyangdp @RollyPeres
updated english in the gist here:
https://gist.github.com/peterennis/35e4ff213a6f98a1c83ecf15600a51c5

@bkarv
Copy link

bkarv commented Dec 8, 2018

@ransoing Thanks your solution worked! However importing google material icons, it imports with a square box around it. Is this normal? I'm importing 24DP svgs.

screen shot 2018-12-08 at 11 56 39 am

screen shot 2018-12-08 at 11 58 23 am

@johnbrattaker
Copy link

@bkarv did you find a solution to this problem. I have the same issue. A black box around the svg.

@bkarv
Copy link

bkarv commented Dec 23, 2018

No i haven't at this moment. I noticed though the SVG file for Ionic icons are blown compared to a small icon in the top left hand corner for google icons. So it has to be something the format setting.

Iconic Icon
screen shot 2018-12-24 at 1 34 20 am

Google Icon
screen shot 2018-12-24 at 1 34 57 am

@bkarv
Copy link

bkarv commented Dec 29, 2018

@bkarv did you find a solution to this problem. I have the same issue. A black box around the svg.

@johnbrattaker
Further to above, although I haven't found solution for google icons but the icons from swift svg icons import without the square box into ionic. https://www.swifticons.com
I am pretty sure you can fix the google icons problem with an svg editor.

@azyth
Copy link

azyth commented Feb 5, 2019

So has anyone been able to do this with a .png image ? In V3 i was able to do it with a hack like below in app.scss

.ion-md-menu{
    background: no-repeat;
    background-position: center;
    background-image: url('assets/icon/lightbulb.png');
    height: 100%;
    background-size: contain;
    color: rgb(60,60,60)!important;
}

@genadis
Copy link

genadis commented Mar 2, 2019

@bkarv did you find a solution to this problem. I have the same issue. A black box around the svg.

@johnbrattaker
Further to above, although I haven't found solution for google icons but the icons from swift svg icons import without the square box into ionic. https://www.swifticons.com
I am pretty sure you can fix the google icons problem with an svg editor.

If it's still relevant. I've found a solution. The border box is actually part of the svg of the material icon when you download it. You can open it in any text editor and delete the rectangle path that looks something like this:
<path fill="none" d="M0 0h24v24H0V0z"/>

@zzmmbb
Copy link

zzmmbb commented Mar 8, 2019

So has anyone been able to do this with a .png image ? In V3 i was able to do it with a hack like below in app.scss

.ion-md-menu{
    background: no-repeat;
    background-position: center;
    background-image: url('assets/icon/lightbulb.png');
    height: 100%;
    background-size: contain;
    color: rgb(60,60,60)!important;
}

image

image

@sg0rd
Copy link

sg0rd commented May 23, 2019

any suggestion with vue.js? 🙏

@xuwenshan
Copy link

How to put the www file directly into your Objective-C project ?

@joshstrange
Copy link

joshstrange commented Jun 28, 2019

Anyone have a good solution to using Font Awesome icons? They don't bundle svg files AFAICT, it's a js file that exports the svg path...

Edit: Of course once I break down to ask for help I figure it out 🙄

I used @ransoing's approach and to make Font Awesome work I downloaded the desktop version of the icons which includes the svg icons. I then duplicated the svg I wanted and prefixed it with ios- and md- then I was able to use it in my tabs 🙌. I wish there was an easy way to expose all of them but this works for now

@SimonBrazell
Copy link

SimonBrazell commented Feb 13, 2020

You can slightly modify the build config to add new icons to the ionicons library, and use them anywhere.

  1. Create a new folder in your project to store your custom icons, i.e. src/assets/custom-ion-icons.
  2. Modify angular.json. Find this section:
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              }
            ],

See how it's packaging all the svg files from the ionic library into "./svg"? Those are the default icons. Whenever you use one of the default icons, your app finds it in that output directory. We can add our own icons to that directory. Add one more object to the "assets" array, so it looks like this:

            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "src/assets/custom-ion-icons",
                "output": "./svg"
              }
            ],
  1. Create your own icons and save them to your custom-ion-icons folder. For each new icon, create two files (one for iOS, one for android/material-design). The following would create a new icon named "newicon":

src/assets/custom-ion-icons/ios-newicon.svg
src/assets/custom-ion-icons/md-newicon.svg

The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

  1. Use your icon anywhere, using the name "newicon"!
<ion-icon name="newicon"></ion-icon>
<ion-tabs>
  <ion-tab label="your-tab-label" icon="newicon" href="/tabs/(home:home)">
    <ion-router-outlet name="your-outlet-name"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

For Ionic v5 the above solution still works, but the ios- and md- prefix is no longer required.

Thanks heaps @ransoing !

@mikev10
Copy link

mikev10 commented Feb 22, 2020

@SimonBrazell I got this to work in v5 as well but the custom icons only show when I serve my app using ‘ionic serve -l’
If I use ‘ionic serve’ I will get 404 errors for all my custom icons.

Is there something else I need to do?

EDIT: I was able to get this working by starting a new app and copying the angular.json file, deleting the node_modules folder and running npm install again, but I cannot style any of the custom icons. For example, I cannot set the color to red.

@SimonBrazell
Copy link

@mikev10 it all worked fine for me, I however varied the instructions for my project slightly by putting my custom icons in icons/ in the root of the project rather than in the src directory as then they will get imported twice I believe. My project was a newly generated one too.

My angular.json projects.app.architect.build.options.assets array looks like this:

"assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/ionicons/dist/ionicons/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "icons", // <= custom icons stored in the project root 'icons' folder
                "output": "./svg"
              }
            ],

If you are having problems colouring the icons then perhaps the problem lies with SVGs themselves, note this part of @ransoing's instructions:

The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

@peterennis
Copy link
Contributor

@SimonBrazell
Ionicons 5 have now 3 types per icon.
Coloring works e.g. https://aeicon5.firebaseapp.com/
with named colors.
When I get a chance to test your implementation I will provide an update here.

@SimonBrazell
Copy link

@peterennis yes this implementation all worked fine for me, colours and everything worked as expected e.g.
<ion-icon name="some-custom-icon" color="primary"></ion-icon>

Ionicons 5 have now 3 types per icon.

You don't need to worry about creating -outline or -sharp variants, unless you want them for your custom icons.

@peterennis
Copy link
Contributor

@SimonBrazell It is working. See this commit: adaept/ae-icon5-component@38133e3
It is a stencil component wrapping the ionicons component so I used the src attribute.
Probably should svgomg the files. Site is updated also.

@umairrafiq1133
Copy link

@SimonBrazell Thanks man. I was using those ios- and md- prefixes. Removing them solved it. Thanks again.

@langy
Copy link

langy commented Mar 19, 2020

@SimonBrazell Thanks so much for this. One tip that might help others out was that my SVGs had fill="#000000" attributes set on the shapes, which turned out to be preventing them from changing colour. Removing these attributes completely fixed that.

@act-node
Copy link

act-node commented Apr 17, 2020

I share the information.
custom icon file name can not be used "_" (under-bar) , like "custome_icon".
If use, the icon can not be shown.

@darkhorse-coder
Copy link

@SimonBrazell Thanks for your work.
But the color is not change real icon color.
<ion-icon name="some-custom-icon" color="primary"></ion-icon>
Do you have any suggestion to change icon color?

@darkhorse-coder
Copy link

@langy Thanks for this.

@SimonBrazell Thanks so much for this. One tip that might help others out was that my SVGs had fill="#000000" attributes set on the shapes, which turned out to be preventing them from changing colour. Removing these attributes completely fixed that.

How can I remove the attribute from SVG element? Please help me.

@SimonBrazell
Copy link

Hi @zhiyilee, you can try open the SVG file in a text editor and look for the style attributes and edit them.

See below (one of the Ionicons) how each of the elements within the svg tag have an individual style attribute containing a fill or stroke style, you can change these in your SVG file if they have colour values that may be interfering with the Ionic colours.

<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'>
        <path d='M384,224V408a40,40,0,0,1-40,40H104a40,40,0,0,1-40-40V168a40,40,0,0,1,40-40H271.48' style='fill:none;stroke:inherit;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px' />
        <polyline points='336 64 448 64 448 176' style='fill:none;stroke:inherit;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px' />
        <line x1='224' y1='288' x2='440' y2='72' style='fill:none;stroke:inherit;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px' />
</svg>

@csherm08
Copy link

csherm08 commented Jul 2, 2022

If you're here you'll also need ``

You can slightly modify the build config to add new icons to the ionicons library, and use them anywhere.

  1. Create a new folder in your project to store your custom icons, i.e. src/assets/custom-ion-icons.
  2. Modify angular.json. Find this section:
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              }
            ],

See how it's packaging all the svg files from the ionic library into "./svg"? Those are the default icons. Whenever you use one of the default icons, your app finds it in that output directory. We can add our own icons to that directory. Add one more object to the "assets" array, so it looks like this:

            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "src/assets/custom-ion-icons",
                "output": "./svg"
              }
            ],
  1. Create your own icons and save them to your custom-ion-icons folder. For each new icon, create two files (one for iOS, one for android/material-design). The following would create a new icon named "newicon":

src/assets/custom-ion-icons/ios-newicon.svg
src/assets/custom-ion-icons/md-newicon.svg
The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

  1. Use your icon anywhere, using the name "newicon"!
<ion-icon name="newicon"></ion-icon>
<ion-tabs>
  <ion-tab label="your-tab-label" icon="newicon" href="/tabs/(home:home)">
    <ion-router-outlet name="your-outlet-name"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

For Ionic v5 the above solution still works, but the ios- and md- prefix is no longer required.

Thanks heaps @ransoing !

You now need *-sharp.svg for your custom icons

@brandyscarney brandyscarney added the triage New issues label Sep 27, 2022
@christian-bromann
Copy link
Member

Consolidating into #1448

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage New issues
Projects
None yet
Development

No branches or pull requests