Multicolored icons
The recommended way to implement multicolored icons is to use CSS variables in SVGs. This will:
-
Eliminate the need to update all images when only one color in the palette changes.
-
Allow designers and developers to work seamlessly and share the same icon sets without any additional manual modifications.
vite-awesome-svg-loader allows you to map a set of predefined colors (or any values for that matter) to a set of CSS
variables (or any other values) via
replaceColorsList option:
export default defineConfig({ plugins: [ viteAwesomeSvgLoader({ replaceColorsList: // Global map of color replacements. Key is an original color, value is its replacement. Both can be any values: // HEX, name, rgb() or arbitrary custom values. Applied to all files. { "#003147": "red", "rgb(0, 49, 71)": "#003147", "myCustomColor": "var(--some-color-var)", },
// Map of color replacements per files { files: ["vars.svg"], // File names or regexes
// Replacements, same format as above replacements: { red: "var(--primary-color)", green: "var(--secondary-color)", blue: "var(--tertiary-color)", },
// Default value for colors that are not in replacements map. Set an empty string to preserve original colors. // Default value is "currentColor", default: "currentColor" }, }), ],}); Rendered demo
Demo's source code
src
assets
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" xml:space="preserve"> <circle fill="red" cx="8.0524569" cy="8.1588478" r="7.8950858" />
<circle fill="blue" cx="15.9475431" cy="8.1588478" r="7.8950858" />
<circle fill="green" cx="12" cy="15.8411522" r="7.8950858" />
<style type="text/css"> circle { opacity: 0.5; } </style></svg><template> <div class="images"> <SvgImage :src="imageSrc" :style="{ '--primary-color': 'red', '--secondary-color': 'green', '--tertiary-color': 'blue', }" /> <SvgImage :src="imageSrc" :style="{ '--primary-color': 'magenta', '--secondary-color': 'cyan', '--tertiary-color': 'yellow', }" /> </div></template>
<script setup lang="ts">import imageSrc from "@/assets/image.svg";import { SvgImage } from "vite-awesome-svg-loader/vue-integration";</script>import { createApp } from "vue";import App from "./App.vue";
const app = createApp(App);app.mount("#app");<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1" /> </head> <body> <div id="app"></div> <script type="module" src="/src/main.ts" ></script> </body></html>{ "name": "vue-multicolored-icons", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "npm run build-only -- --watch", "build": "run-p type-check \"build-only {@}\" --", "build-only": "vite build --config vite.config.lib.ts", "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false" }, "dependencies": { "vite-awesome-svg-loader": "*", "vite-file-tree-builder": "*" }}{ "extends": "@vue/tsconfig/tsconfig.dom.json", "include": ["src/**/*", "src/**/*.vue"], "compilerOptions": { "composite": true, "baseUrl": ".", "paths": { "@/*": ["./src/*"] },
"types": [ // Add types for query imports (for example, "@/some/file.svg?src"). // Unfortunately, it's impossible to fully type it. Use plugin configuration instead. "vite-awesome-svg-loader",
"vite/client", // Vite types "vite-file-tree-builder" // Internal types ] }}{ "files": [], "references": [ { "path": "./tsconfig.node.json" }, { "path": "./tsconfig.app.json" } ]}{ "extends": "@tsconfig/node18/tsconfig.json", "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "nightwatch.conf.*", "playwright.config.*"], "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "Bundler", "types": ["node"] }}import { fileURLToPath, URL } from "node:url";import { defineConfig } from "vite";import vue from "@vitejs/plugin-vue";
// Import vite-awesome-svg-loaderimport { viteAwesomeSvgLoader } from "vite-awesome-svg-loader";
export default defineConfig({ plugins: [ vue(), viteAwesomeSvgLoader({ replaceColorsList: [ { files: ["image.svg"], // File names or regexes
// Replacements, same format as above replacements: { red: "var(--primary-color)", green: "var(--secondary-color)", blue: "var(--tertiary-color)", },
// Default value for colors that are not in replacements map. Set an empty string to preserve original colors. // Default value is "currentColor", default: "currentColor", }, ],
urlImportsInLibraryMode: "emit-files", }), ], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), }, },});
Please open file to view its content