Tom wang
Tom wang

Reputation: 33

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?

Upvotes: 1

Views: 3007

Answers (2)

Ibrahim.H
Ibrahim.H

Reputation: 1195

Here is a simple wrap-up ready to use component (TypeScript & composition api):

src/components/b-icon.vue:

<script lang="ts" setup>
import iconPath from 'bootstrap-icons/bootstrap-icons.svg'

defineProps({
    name: {
        type: String,
        required: true
    },
    size: {
        type: Number,
        required: false,
        default: 32
    },
    fill: {
        type: String,
        required: false,
        default: 'currentColor'
    }
})
</script>

<template>
    <svg class="bi" :width="size" :height="size" :fill="fill">
        <use :xlink:href="`${iconPath}#${name}`"/>
    </svg>
</template>

Usage demo:

<b-icon name="lock-fill" />

You just need to npm install bootstrap-icons.

Upvotes: 1

Markus
Markus

Reputation: 6288

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>

Upvotes: 3

Related Questions