├── .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 |
2 |
3 |
4 |
file-loader
5 |
6 |
7 |
8 |
9 |
url-loader
10 |
11 |
12 |
13 |
14 |
vue-svg-loader
15 |
16 |
17 |
18 |
19 |
raw-loader
20 |
21 |
22 |
23 |
24 |
svg-sprite-loader
25 |
26 |
27 |
28 |
29 |
30 |
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 |
83 |
84 |
85 | ```
86 |
87 | ```html
88 |
89 | ```
90 |
91 | ### `url-loader`
92 |
93 | ```html
94 |
95 |
96 |
97 | ```
98 |
99 | ```html
100 |
101 | ```
102 |
103 | ### `vue-svg-loader`
104 |
105 | ```html
106 |
107 |
108 |
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 |
129 |
130 |
131 |
132 |
141 | ```
142 |
143 | ```html
144 |
149 | ```
150 |
151 | ### `svg-sprite-loader`
152 |
153 | ```html
154 |
155 |
156 |
157 |
158 |
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 |
183 |
184 |
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 |
201 |
202 |
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 |
--------------------------------------------------------------------------------