1 | # vue-svg-inline-plugin
|
2 |
|
3 | [![version](https://img.shields.io/npm/v/vue-svg-inline-plugin.svg?style=flat)][npm]
|
4 | [![downloads](https://img.shields.io/npm/dt/vue-svg-inline-plugin.svg?style=flat)][npm]
|
5 | [![license](https://img.shields.io/npm/l/vue-svg-inline-plugin.svg?style=flat)][mit]
|
6 | [![paypal](https://img.shields.io/badge/donate-paypal-blue.svg?colorB=0070ba&style=flat)](https://paypal.me/oliverfindl)
|
7 |
|
8 | [Vue][vue] plugin for inline replacement of SVG images with actual content of SVG files.
|
9 |
|
10 | > ⚠ Reactive [Vue][vue] bindings won't be transfered to SVG replacement.
|
11 |
|
12 | > SVG files should be optimized beforehand (e.g.: using [SVGO](https://www.npmjs.com/package/svgo) or [SVGOMG](https://jakearchibald.github.io/svgomg/)).
|
13 |
|
14 | > Placeholder images should be optimized beforehand (e.g.: using [pngquant](https://pngquant.org/) or [TinyPNG](https://tinypng.com/) / [TinyJPG](https://tinyjpg.com/)).
|
15 |
|
16 | > Compatible with [Vue][vue]@2 and [Vue][vue]@3.
|
17 |
|
18 | ---
|
19 |
|
20 | ## Table of contents:
|
21 | * [Installation](#installation)
|
22 | * [Usage](#usage)
|
23 | * [Directive](#directive)
|
24 | * [Lazy loading](#lazy-loading)
|
25 | * [Configuration](#configuration)
|
26 | * [Polyfills](#polyfills)
|
27 | * [Examples](#examples)
|
28 |
|
29 | ---
|
30 |
|
31 | ## Installation
|
32 |
|
33 | ### Package managers
|
34 |
|
35 | * [npm](https://npmjs.com/) [[package][npm]]:
|
36 | ```bash
|
37 | $ npm install vue-svg-inline-plugin --save
|
38 | ```
|
39 |
|
40 | * [yarn](https://yarnpkg.com/en/) [[package](https://yarnpkg.com/en/package/vue-svg-inline-plugin)]:
|
41 | ```bash
|
42 | $ yarn add vue-svg-inline-plugin
|
43 | ```
|
44 |
|
45 | ### Legacy browsers
|
46 |
|
47 | * [unpkg](https://unpkg.com/) [[package](https://www.unpkg.com/browse/vue-svg-inline-plugin/)]:
|
48 | ```html
|
49 | <script src="//unpkg.com/vue-svg-inline-plugin"></script>
|
50 | ```
|
51 |
|
52 | * [jsDelivr](https://jsdelivr.com/) [[package](https://www.jsdelivr.com/package/npm/vue-svg-inline-plugin)]:
|
53 | ```html
|
54 | <script src="//cdn.jsdelivr.net/npm/vue-svg-inline-plugin"></script>
|
55 | ```
|
56 |
|
57 | ### Modern browsers
|
58 |
|
59 | > This version is not transpiled and does not include any [polyfills](#polyfills).
|
60 |
|
61 | * [unpkg](https://unpkg.com/) [[package](https://www.unpkg.com/browse/vue-svg-inline-plugin/)]:
|
62 | ```html
|
63 | <script src="//unpkg.com/vue-svg-inline-plugin/dist/vue-svg-inline-plugin-modern.min.js"></script>
|
64 | ```
|
65 |
|
66 | * [jsDelivr](https://jsdelivr.com/) [[package](https://www.jsdelivr.com/package/npm/vue-svg-inline-plugin)]:
|
67 | ```html
|
68 | <script src="//cdn.jsdelivr.net/npm/vue-svg-inline-plugin/dist/vue-svg-inline-plugin-modern.min.js"></script>
|
69 | ```
|
70 |
|
71 | ## Usage
|
72 |
|
73 | ### [Webpack][webpack] based [Vue][vue] projects (e.g.: [Webpack][webpack] or [Vue CLI][vue-cli]) and [Vite][vite] projects
|
74 |
|
75 | ```javascript
|
76 | // Vue@2
|
77 |
|
78 | // import basic Vue app
|
79 | import Vue from "vue";
|
80 | import App from "./App.vue";
|
81 |
|
82 | // import Vue plugin
|
83 | import VueSvgInlinePlugin from "vue-svg-inline-plugin";
|
84 |
|
85 | // import polyfills for IE if you want to support it
|
86 | import "vue-svg-inline-plugin/src/polyfills";
|
87 |
|
88 | // use Vue plugin without options
|
89 | Vue.use(VueSvgInlinePlugin);
|
90 |
|
91 | // use Vue plugin with options
|
92 | VueSvgInlinePlugin.install(Vue, {
|
93 | attributes: {
|
94 | data: [ "src" ],
|
95 | remove: [ "alt" ]
|
96 | }
|
97 | });
|
98 |
|
99 | // initialize and mount Vue app
|
100 | new Vue({
|
101 | render: h => h(App),
|
102 | }).$mount("#app");
|
103 | ```
|
104 |
|
105 | ```javascript
|
106 | // Vue@3
|
107 |
|
108 | // import basic Vue app
|
109 | import { createApp } from "vue";
|
110 | import App from "./App.vue";
|
111 |
|
112 | // import Vue plugin
|
113 | import VueSvgInlinePlugin from "vue-svg-inline-plugin";
|
114 |
|
115 | // import polyfills for IE if you want to support it
|
116 | import "vue-svg-inline-plugin/src/polyfills";
|
117 |
|
118 | // initialize Vue app
|
119 | const app = createApp(App);
|
120 |
|
121 | // use Vue plugin without options
|
122 | app.use(VueSvgInlinePlugin);
|
123 |
|
124 | // use Vue plugin with options
|
125 | app.use(VueSvgInlinePlugin, {
|
126 | attributes: {
|
127 | data: [ "src" ],
|
128 | remove: [ "alt" ]
|
129 | }
|
130 | });
|
131 |
|
132 | // mount Vue app
|
133 | app.mount("#app");
|
134 | ```
|
135 |
|
136 | ### Browsers
|
137 |
|
138 | ```javascript
|
139 | // Vue@2
|
140 |
|
141 | // use Vue plugin without options
|
142 | Vue.use(VueSvgInlinePlugin);
|
143 |
|
144 | // use Vue plugin with options
|
145 | VueSvgInlinePlugin.install(Vue, {
|
146 | attributes: {
|
147 | data: [ "src" ],
|
148 | remove: [ "alt" ]
|
149 | }
|
150 | });
|
151 |
|
152 | // initialize and mount Vue app
|
153 | new Vue({ /* options */ }).$mount("#app");
|
154 | ```
|
155 |
|
156 | ```javascript
|
157 | // Vue@3
|
158 |
|
159 | // initialize Vue app
|
160 | const app = Vue.createApp({ /* options */ });
|
161 |
|
162 | // use Vue plugin without options
|
163 | app.use(VueSvgInlinePlugin);
|
164 |
|
165 | // use Vue plugin with options
|
166 | app.use(VueSvgInlinePlugin, {
|
167 | attributes: {
|
168 | data: [ "src" ],
|
169 | remove: [ "alt" ]
|
170 | }
|
171 | });
|
172 |
|
173 | // mount Vue app
|
174 | app.mount("#app");
|
175 | ```
|
176 |
|
177 | ## Directive
|
178 |
|
179 | > Directive name can be changed via [options](#configuration).
|
180 |
|
181 | **`v-svg-inline`** directive:
|
182 |
|
183 | ```html
|
184 | <img v-svg-inline class="icon" src="./images/example.svg" alt="example svg image" />
|
185 | ```
|
186 | Replaces into:
|
187 | ```xml
|
188 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="..." class="icon" focusable="false" role="presentation" tabindex="-1">
|
189 | <path d="..."></path>
|
190 | <!-- ... -->
|
191 | </svg>
|
192 | ```
|
193 |
|
194 | **`v-svg-inline`** directive with **`sprite`** modifier:
|
195 | > ~~⚠ Note, that for now, the `viewBox` property is not being applied on the `<svg>` link node.
|
196 | This can cause issues when having icons differently sized in your UI.
|
197 | For the most icon-systems, you can add a `viewBox="0 0 24 24"` by yourself onto the `<img>` node or use [`attributes.add` option](#configuration).~~
|
198 |
|
199 | > Fixed in version 2.1.0, use [`attributes.clone` option](#configuration).
|
200 |
|
201 | ```html
|
202 | <img v-svg-inline.sprite class="icon" src="./images/example.svg" alt="example svg image" />
|
203 | ```
|
204 | Replaces into:
|
205 | ```xml
|
206 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="..." class="icon" focusable="false" role="presentation" tabindex="-1">
|
207 | <use xlink:href="#svg-inline-plugin-sprite-<NUMBER>" href="#svg-inline-plugin-sprite-<NUMBER>"></use>
|
208 | </svg>
|
209 | <!-- ... -->
|
210 | <!-- injected before body closing tag -->
|
211 | <svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">
|
212 | <symbol id="svg-inline-plugin-sprite-<NUMBER>" xmlns="http://www.w3.org/2000/svg" viewBox="...">
|
213 | <path d="..."></path>
|
214 | <!-- ... -->
|
215 | </symbol>
|
216 | </svg>
|
217 | ```
|
218 |
|
219 | ## Lazy loading
|
220 |
|
221 | This plugin supports lazy (down)loading of SVG files. To enable it, rename `src` attribute to `data-src`. Please also provide placeholder image, which should be located in `src` attribute to avoid broken image icons in browsers.
|
222 |
|
223 | ## Configuration
|
224 |
|
225 | ### Default options
|
226 |
|
227 | ```javascript
|
228 | {
|
229 | directive: {
|
230 | name: "v-svg-inline",
|
231 | spriteModifierName: "sprite"
|
232 | },
|
233 | attributes: {
|
234 | clone: [ "viewbox" ],
|
235 | merge: [ "class", "style" ],
|
236 | add: [ {
|
237 | name: "focusable",
|
238 | value: false
|
239 | }, {
|
240 | name: "role",
|
241 | value: "presentation"
|
242 | }, {
|
243 | name: "tabindex",
|
244 | value: -1
|
245 | } ],
|
246 | data: [],
|
247 | remove: [ "alt", "src", "data-src" ]
|
248 | },
|
249 | cache: {
|
250 | version: "<PACKAGE_VERSION>",
|
251 | persistent: true,
|
252 | removeRevisions: true
|
253 | },
|
254 | intersectionObserverOptions: {},
|
255 | axios: null,
|
256 | xhtml: false
|
257 | }
|
258 | ```
|
259 |
|
260 | ### Explanation
|
261 |
|
262 | * **`directive.name`:**
|
263 | Defines directive name (lowercase string), which marks images you want to replace with inline SVGs.
|
264 |
|
265 | * **`directive.spriteModifierName`:**
|
266 | Defines directive modifier name (lowercase string), which together with `directive.name` marks images you want to replace with inline SVGs using inline SVG sprites.
|
267 |
|
268 | * **`attributes.clone`:**
|
269 | Array of attributes (lowercase strings) which should be cloned into SVG link node if using inline SVG sprites.
|
270 |
|
271 | * **`attributes.merge`:**
|
272 | Array of attributes (lowercase strings) which should be merged.
|
273 |
|
274 | * **`attributes.add`:**
|
275 | Array of attributes (objects with name (lowercase string) and value (string) properties), which should be added. If attribute already exists, it will be merged or skipped depending on `attributes.merge` option.
|
276 |
|
277 | * **`attributes.data`:**
|
278 | Array of attributes (lowercase strings) which should be transformed into data-attributes. If data-attribute already exists, it will be merged or skipped depending on `attributes.merge` option.
|
279 |
|
280 | * **`attributes.remove`:**
|
281 | Array of attributes (lowercase strings) which should be removed.
|
282 |
|
283 | * **`cache.version`:**
|
284 | Defines cache version (lowercase string or number).
|
285 |
|
286 | * **`cache.persistent`:**
|
287 | Boolean. Cache downloaded SVG files into local storage.
|
288 |
|
289 | * **`cache.removeRevisions`:**
|
290 | Boolean. Remove previous cache revisions from local storage.
|
291 |
|
292 | * **`intersectionObserverOptions`:**
|
293 | Intersection observer options object for processing image nodes. This option is not validated. [Official documentation](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options).
|
294 |
|
295 | * **`axios`:**
|
296 | Axios instance with pre-configured options. If omitted, new axios instance (if axios available) will be created. [Official documentation](https://github.com/axios/axios#creating-an-instance).
|
297 |
|
298 | * **`xhtml`:**
|
299 | Boolean. In XHTML mode attribute minimization is forbidden. Empty attributes are filled with their names to be XHTML-compliant (e.g.: disabled="disabled").
|
300 |
|
301 | ### Notices
|
302 |
|
303 | * User-defined options are deep-merged with default options. Arrays are not concatenated.
|
304 |
|
305 | * Attributes options are executed in this order: **clone > merge** > **add** > **data** > **remove**.
|
306 |
|
307 | ## Polyfills
|
308 |
|
309 | Required polyfills for IE:
|
310 |
|
311 | * [fetch](https://github.com/github/fetch) polyfill or [axios](https://github.com/axios/axios) library
|
312 | * [IntersectionObserver](https://github.com/w3c/IntersectionObserver) polyfill
|
313 |
|
314 | ## Examples
|
315 |
|
316 | * [Vue][vue]@2:
|
317 | * [browser example](https://github.com/oliverfindl/vue-svg-inline-plugin/tree/master/examples/browser-vue2)
|
318 | * [vue-cli example](https://github.com/oliverfindl/vue-svg-inline-plugin/tree/master/examples/vue-cli-vue2)
|
319 | * [webpack example](https://github.com/oliverfindl/vue-svg-inline-plugin/tree/master/examples/webpack-vue2)
|
320 | * [Vue][vue]@3:
|
321 | * [browser example](https://github.com/oliverfindl/vue-svg-inline-plugin/tree/master/examples/browser-vue3)
|
322 | * [vite example](https://github.com/oliverfindl/vue-svg-inline-plugin/tree/master/examples/vite-vue3)
|
323 | * [webpack example](https://github.com/oliverfindl/vue-svg-inline-plugin/tree/master/examples/webpack-vue3)
|
324 |
|
325 | ---
|
326 |
|
327 | ## License
|
328 |
|
329 | [MIT][mit]
|
330 |
|
331 | [mit]: https://opensource.org/licenses/MIT
|
332 | [npm]: https://www.npmjs.com/package/vue-svg-inline-plugin
|
333 | [vue]: https://github.com/vuejs/vue
|
334 | [vue-cli]: https://github.com/vuejs/vue-cli
|
335 | [vite]: https://github.com/vitejs/vite
|
336 | [webpack]: https://github.com/webpack/webpack
|