├── .gitignore ├── example ├── nuxt.config.js ├── assets │ └── nuxt.svg └── pages │ └── index.vue ├── lib ├── config.js └── module.js ├── package.json ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt 6 | .vscode 7 | .DS_Store 8 | coverage 9 | dist 10 | -------------------------------------------------------------------------------- /example/nuxt.config.js: -------------------------------------------------------------------------------- 1 | import svgModule from "../lib/module"; 2 | 3 | export default { 4 | buildModules: [svgModule], 5 | }; 6 | -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | const getFileLoaderDefaultConfig = ({ isDev }) => ({ 2 | name: isDev ? "[path][name].[ext]" : "img/[name].[contenthash:7].[ext]", 3 | }); 4 | 5 | module.exports.getFileLoaderDefaultConfig = getFileLoaderDefaultConfig; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nuxtjs/svg", 3 | "version": "0.4.1", 4 | "description": "Super simple svg loading module for Nuxt.js", 5 | "keywords": [ 6 | "nuxt", 7 | "nuxt-module", 8 | "nuxtjs", 9 | "svg", 10 | "vue" 11 | ], 12 | "repository": "nuxt-community/svg-module", 13 | "license": "MIT", 14 | "author": "Sam Holmes", 15 | "files": [ 16 | "lib" 17 | ], 18 | "main": "lib/module.js", 19 | "scripts": { 20 | "dev": "nuxt dev example", 21 | "generate": "nuxt generate example", 22 | "start": "nuxt start example", 23 | "format": "prettier --write '**/*.{js,json,vue}'" 24 | }, 25 | "dependencies": { 26 | "file-loader": "^6.0.0", 27 | "raw-loader": "^4.0.0", 28 | "svg-sprite-loader": "^5.2.1", 29 | "url-loader": "^4.1.0", 30 | "vue-svg-loader": "^0.16.0" 31 | }, 32 | "devDependencies": { 33 | "nuxt": "^2.12.2", 34 | "prettier": "^2.0.4" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sam Holmes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/assets/nuxt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/pages/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 45 | 46 | 73 | -------------------------------------------------------------------------------- /lib/module.js: -------------------------------------------------------------------------------- 1 | const { getFileLoaderDefaultConfig } = require("./config"); 2 | 3 | /** 4 | * This is the original RegExp cloned from the original Nuxt.js configuration 5 | * files, with only the search for ".svg" files removed. Keep tabs on this in 6 | * case the core decides to add additional qualifiers to the pattern. 7 | */ 8 | const ORIGINAL_TEST = /\.(png|jpe?g|gif|svg|webp|avif)$/i; 9 | const ORIGINAL_TEST_OLD_NUXT = /\.(png|jpe?g|gif|svg|webp)$/i; 10 | const REPLACEMENT_TEST = /\.(png|jpe?g|gif|webp|avif)$/i; 11 | 12 | export default function svgModule(moduleOptions) { 13 | const options = Object.assign({}, this.options.svg, moduleOptions); 14 | this.extendBuild(setup.bind(this, options)); 15 | } 16 | 17 | /** 18 | * Perform the primary setup for the nuxt-svg module by removing and replacing 19 | * all of the rules that match ".svg" with the new one. 20 | * 21 | * @param options The module options 22 | * @param config The webpack configuration object to extend 23 | * @param context Nuxt webpack env 24 | */ 25 | function setup(options, config, context) { 26 | const fileLoaderOptions = Object.assign( 27 | {}, 28 | getFileLoaderDefaultConfig(context), 29 | typeof options.fileLoader === "function" 30 | ? options.fileLoader(context) 31 | : options.fileLoader 32 | ); 33 | 34 | const rules = config.module.rules; 35 | 36 | // Remove any original svg rules. 37 | const svgRules = rules.filter((rule) => rule.test && rule.test.test(".svg")); 38 | 39 | for (const rule of svgRules) { 40 | if ( 41 | rule.test.source !== ORIGINAL_TEST.source && 42 | rule.test.source !== ORIGINAL_TEST_OLD_NUXT.source && 43 | rule.test.source !== REPLACEMENT_TEST.source 44 | ) { 45 | throw new Error( 46 | "nuxt-svg: Unexpected '.svg' rule in the webpack configuration" 47 | ); 48 | } 49 | rule.test = REPLACEMENT_TEST; 50 | } 51 | 52 | const vueSvgLoader = [ 53 | { 54 | loader: "vue-svg-loader", 55 | options: options.vueSvgLoader || { svgo: false }, 56 | }, 57 | ]; 58 | 59 | if (config.name !== "server") { 60 | const jsxRule = config.module.rules.find((r) => r.test.test(".jsx")); 61 | const babelLoader = jsxRule.use[jsxRule.use.length - 1]; 62 | vueSvgLoader.unshift(babelLoader); 63 | } 64 | 65 | /** 66 | * Create the custom rule that supports multiple resource queries. By default, 67 | * use file-loader (no resource query supplied). 68 | */ 69 | const rule = { 70 | test: /\.svg$/i, 71 | oneOf: [ 72 | { 73 | resourceQuery: /inline/, 74 | use: vueSvgLoader, 75 | }, 76 | { 77 | resourceQuery: /data/, 78 | use: { 79 | loader: "url-loader", 80 | options: { esModule: false }, 81 | }, 82 | }, 83 | { 84 | resourceQuery: /raw/, 85 | use: { 86 | loader: "raw-loader", 87 | options: { esModule: false }, 88 | }, 89 | }, 90 | { 91 | resourceQuery: /sprite/, 92 | use: { 93 | loader: "svg-sprite-loader", 94 | options: options.svgSpriteLoader || {}, 95 | }, 96 | }, 97 | { 98 | use: { 99 | loader: "file-loader", 100 | options: { esModule: false, ...fileLoaderOptions }, 101 | }, 102 | }, 103 | ], 104 | }; 105 | 106 | rules.push(rule); // Add the rule to the configuration. 107 | } 108 | 109 | module.exports.meta = require("../package.json"); 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @nuxtjs/svg 2 | 3 | [![npm version][npm-version-src]][npm-version-href] 4 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 5 | [![License][license-src]][license-href] 6 | 7 | _Super simple svg loading module for Nuxt.js_ 8 | 9 | - [@nuxtjs/svg](#nuxtjssvg) 10 | - [Introduction](#introduction) 11 | - [Installation](#installation) 12 | - [Usage](#usage) 13 | - [`file-loader`](#file-loader) 14 | - [`url-loader`](#url-loader) 15 | - [`vue-svg-loader`](#vue-svg-loader) 16 | - [`raw-loader`](#raw-loader) 17 | - [`svg-sprite-loader`](#svg-sprite-loader) 18 | - [Caveats](#caveats) 19 | - [Contributing](#contributing) 20 | - [License](#license) 21 | 22 | ## Introduction 23 | 24 | This package is for loading SVG's into Nuxt.js pages. It allows you to import `.svg` files in multiple ways depending on the [resource query](https://webpack.js.org/configuration/module/#rule-resourcequery) you provide. Currently, this allows you to do the following: 25 | 26 | - `file.svg` - normal import using `file-loader` 27 | - `file.svg?data` - base64 data url import using `url-loader` 28 | - `file.svg?inline` - inline import using `vue-svg-loader` 29 | - `file.svg?raw` - raw html import using `raw-loader` 30 | - `file.svg?sprite` - SVG sprite using `svg-sprite-loader` 31 | 32 | ## Installation 33 | 34 | ```shell 35 | npm install --save-dev @nuxtjs/svg 36 | ``` 37 | 38 | ```javascript 39 | // nuxt.config.js 40 | export default { 41 | buildModules: ["@nuxtjs/svg"], 42 | }; 43 | ``` 44 | 45 | And that's it! You don't have to install anything else, you're ready to go. 46 | 47 | ## Configuration 48 | 49 | ```javascript 50 | // nuxt.config.js 51 | export default { 52 | svg: { 53 | vueSvgLoader: { 54 | // vue-svg-loader options 55 | }, 56 | svgSpriteLoader: { 57 | // svg-sprite-loader options 58 | }, 59 | fileLoader: { 60 | // file-loader options 61 | } 62 | } 63 | }; 64 | ``` 65 | 66 | 67 | ## Usage 68 | 69 | The usage examples are documented as: 70 | 71 | ```html 72 | 73 | ``` 74 | 75 | ```html 76 | 77 | ``` 78 | 79 | ### `file-loader` 80 | 81 | ```html 82 | 85 | ``` 86 | 87 | ```html 88 | 89 | ``` 90 | 91 | ### `url-loader` 92 | 93 | ```html 94 | 97 | ``` 98 | 99 | ```html 100 | 101 | ``` 102 | 103 | ### `vue-svg-loader` 104 | 105 | ```html 106 | 109 | 110 | 117 | ``` 118 | 119 | ```html 120 | 121 | ``` 122 | 123 | ### `raw-loader` 124 | 125 | Load the raw SVG data as HTML using `raw-loader`: 126 | 127 | ```html 128 | 131 | 132 | 141 | ``` 142 | 143 | ```html 144 |
145 | 146 | 147 | 148 |
149 | ``` 150 | 151 | ### `svg-sprite-loader` 152 | 153 | ```html 154 | 159 | 160 | 169 | ``` 170 | 171 | ```html 172 | 173 | 174 | 175 | ``` 176 | 177 | ## Dynamic imports 178 | 179 | To dynamically import an SVG, you can use the inline `require()` syntax. 180 | 181 | ```html 182 | 185 | 186 | 193 | ``` 194 | 195 | > This example uses `raw-loader`. 196 | 197 | To render an SVG without wrapper element and the use of `v-html`, a combination of [dynamic components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components) and `?inline` can be used. See #72 for context. 198 | 199 | ```html 200 | 203 | 204 | 211 | ``` 212 | 213 | > This example uses `vue-svg-loader`. 214 | 215 | ## Caveats 216 | 217 | In order for this module to work correctly, the [default `.svg` Nuxt.js webpack rule](https://nuxtjs.org/guide/assets/#webpack) gets replaced with this handler. 218 | 219 | The only difference between this and the handler is that there is no `limit` for when `file-loader` replaces `url-loader`. 220 | 221 | So when using the `?data` query, it will _always_ use `url-loader` regardless of file size, and when not using either resource query, it will always use `file-loader`). 222 | 223 | ## Contributing 224 | 225 | As this loader attempts to abstract webpack configuration from the process and make it easier to use multiple svg loaders, any contributions that add more svg loader methods to the configuration will be accepted wholeheartedly! 226 | 227 | ## License 228 | 229 | [MIT License](./LICENSE) 230 | 231 | Copyright (c) Sam Holmes 232 | 233 | 234 | 235 | [npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/svg/latest.svg?style=flat-square 236 | [npm-version-href]: https://npmjs.com/package/@nuxtjs/svg 237 | [npm-downloads-src]: https://img.shields.io/npm/dt/@nuxtjs/svg.svg?style=flat-square 238 | [npm-downloads-href]: https://npmjs.com/package/@nuxtjs/svg 239 | [license-src]: https://img.shields.io/npm/l/@nuxtjs/svg.svg?style=flat-square 240 | [license-href]: https://npmjs.com/package/@nuxtjs/svg 241 | --------------------------------------------------------------------------------