Mapping custom SVG icons



  • Hi,
    I’m trying to map my own SVG icons according to the documentation. But I probably can’t enter the path to the file correctly (I probably don’t understand how it works). I always get a 404 response for icon (resource not found). Can you please advise me how to enter the path to the SVG icon file correctly? The icon is located in the /src/assets/ directory.

    I tried:
    img:/assets/pac-man.svg
    img:~assets/pac-man.svg
    img:/src/assets/pac-man.svg
    img:./assets/pac-man.svg
    and lots of others…

    <template>
      <div id="q-app">
        <router-view />
      </div>
    </template>
    
    <script>
    const appIcons = {
      'app:pacman': 'img:/assets/pac-man.svg'
    }
    
    export default {
      name: 'App',
      created () {
        this.$q.iconMapFn = (iconName) => {
          const icon = appIcons[iconName]
          if (icon !== undefined) {
            return { icon: icon }
          }
        }
      }
    }
    </script>
    
    

  • Admin

    You don’t need img:

    Just do: 'app:pacman': 'src/assets/pac-man.svg'

    Or better still, if your icons are in the same location, change your array to just have the icon svg part and include the path in your map function as it won’t change.



  • @Allan-EN-GB Thank you for answer. The icon not show (this will probably be another problem), but I no longer get a 404 error. A little question: what does the img prefix mean? It is used in the documentation before the svg file, in the example to map icons.


  • Admin

    It treats the file as an image (which I suppose is correct here): https://quasar.dev/vue-components/icon#Image-icons

    I wonder if your issue is that fact the icons are in assets and not public.

    This is how I do it:

    const iconPath = 'img:app-icons/new/'
    const myIcons: { [key:string]: string } = {
      'app:penName': 'pen-names.svg',
      'app:ban': 'ban.svg',
      'app:link': 'link.svg',
      'app:book': 'book.svg',
      'app:delayed': 'delayed.svg',
      'app:teams-person': 'teams-person.svg',
      'app:unread': 'unread.svg',
      'app:inbox': 'inbox.svg',
      'app:sent': 'sent.svg',
      'app:trash': 'trash.svg',
      'app:block': 'block.svg',
      'app:arrow-left': 'arrow-left.svg',
      'app:flag': 'flag.svg'
    }
    
    this.$q.iconMapFn = (iconName) => {
          const icon = myIcons[iconName]
          if (icon !== void 0) {
            return { icon: iconPath + icon }
          }
          return void 0
        }
    
    

    And my icons are in /public/app-icons/new



  • @Allan-EN-GB Great, thank you. It works now. As soon as I moved the icons from /src/assets to /public/appIcons, everything started working. I still have to find out why this is so, but the main thing is that it works 🙂 Thank you!



  • @Allan-EN-GB And now I have one last question for you. Is it possible to color your own svg icon? By that I mean that the icon responds to the color property in the q-icon. Do I have to create svg in a special way or is it not possible with SVG at all?

    <q-icon color="blue" name="pacman" />
    

  • Admin

    Assets are compiled assets, statics are static. Check the docs to see why they’re different: https://quasar.dev/quasar-cli/handling-assets#Introduction

    For coloring: See this codepen: https://codepen.io/sosuke/pen/Pjoqqp

    It lets you put in a HEX value then gives you the appropriate filter to color the SVG.

    Take note of their comment:

    For this code to work well the starting color needs to be black. If your icon set isn’t black you can prepend “brightness(0) saturate(100%)” to your filter property which will first turn the icon set to black.



  • @Allan-EN-GB Thanks again, you helped me a lot. It won’t be that easy with coloring, but I will definitely be able to do it.


  • Admin

    No problem 🙂



  • @Allan-EN-GB I’m trying to do the same thing, but I fail.

    App.vue :

    <template>
      <div id="q-app">
        <router-view />
      </div>
    </template>
    
    <script>
    const appIcons = {
      'app:my-icon': 'img:customIcons/my-icon.svg'
    }
    
    export default {
      name: 'App',
      created () {
        this.$q.iconMapFn = (iconName) => {
          const icon = appIcons[iconName]
          if (icon !== undefined) {
            return { icon: icon }
          }
        }
      }
    }
    </script>
    

    my-icon.svg is in public/customIcons (public is at the same level as src)

    <q-icon
      name="app:my-icon"
      @error="logError"
    />
    

    and

    <q-icon
      name="img:customIcons/my-icon.svg"
      @error="logError"
    />
    

    log the same error, including:
    target: img.q-icon.notranslate
    currentSrc: "http://localhost:8080/customIcons/my-icon.png"

    if I try accessing http://localhost:8080/customIcons/my-icon.png, then I get a page with: “Cannot GET /customIcons/my-icon.svg”

    Any idea about what I am doing wrong ?


Log in to reply