twitter-bootstrapvue.jsiconsvue-cli

How to use bootstrap-icons as svgs in a vue project build by vue-cli


I tried to use bootstrap-icons library in my vue project, right now I just import the CSS file so I can use as a icon font("i" tag).But I want to use them as svgs so I can use linear-gradient for color filling.

I installed bootstrap-icons to my project with

npm i bootstrap-icons

and use try to use them as it said on the website:

<svg class="bi" width="32" height="32" fill="currentColor">
  <use xlink:href="bootstrap-icons.svg#heart-fill"/>
</svg>

It's not working, and I tried to use require() for the xlink:href or use v-bind to link the value to a var, none of them work, throwing error with "Cannot find module" or "Get 404". I tried to copy the bootstrap-icons document out side the node_modules and put it under the root, change the value of xlink:href to be "bootstrap-icons/bootstrap-icons.svg#heart-fill", still not working.

I'm a noob for vue and I build this project with vue-cli. I cannot figure out what is going on with this problem and I didn't find the solution on the Internet. Did any one meet the same problem before?


Solution

  • static link

    You can use the ~ shortcut to reference assets in node_modules (see here):

    <svg class="bi" width="32" height="32" fill="currentColor">
      <use xlink:href="~/bootstrap-icons/bootstrap-icons.svg#heart-fill"/>
    </svg>
    

    dynamic link

    If you need dynamic binding you can use the fact that require returns a path to the required svg-file:

    <template>
      <svg class="bi" width="32" height="32" fill="currentColor">
        <use :xlink:href="`${iconUrl}`"/>
      </svg>
    </template>
    
    <script>
    const iconPath = require('bootstrap-icons/bootstrap-icons.svg');
    
    export default {
      name: 'App',
      data() {
        return {
          iconUrl: iconPath + '#heart-fill'
        };
      }
    };
    </script>
    

    You can do the same with import instead of require:

    import iconPath from 'bootstrap-icons/bootstrap-icons.svg'
    

    If you wonder where this behaviour is defined you can inspect your default vue-cli webpack-config as described here.

    font

    Although this is not exactly what you where asking for you could use the CSS icon font instead of svg:

    <template>
      <i :class="iconClass" style="font-size: 32px;"></i>
    </template>
    
    <script>
    export default {
      name: 'App',
      data() {
        return {
          iconClass: 'bi-heart-fill'
        };
      }
    };
    </script>
    
    <style>
      @import "bootstrap-icons/font/bootstrap-icons.css";
    </style>