Nuxt.js: Vue-svg-loader not working with Nuxt

Created on 18 Aug 2018  路  10Comments  路  Source: nuxt/nuxt.js

Version

v1.4.2

Reproduction link

https://github.com/FistMeNaruto/vue-svg-loader-test

Steps to reproduce

Do everything described in https://vue-svg-loader.js.org/ documentation.

What is expected ?

SVG of a circle on the homepage

What is actually happening?

SVG gets converted to base64 even though svg files should not be processed by the url loader anymore.

Additional comments?

Issue on vue-svg-loader repo: visualfanatic/vue-svg-loader#41

This bug report is available on Nuxt community (#c7599)
bug-report

Most helpful comment

it does fail because you apply the loader only client-side, not on both sides.

This will work out ;)

extend(config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: "pre",
          test: /\.(js|vue)$/,
          loader: "eslint-loader",
          exclude: /(node_modules)/
        });
      }
      config.module.rules
        .filter(r => r.test.toString().includes("svg"))
        .forEach(r => {
          r.test = /\.(png|jpe?g|gif)$/;
       });
      config.module.rules.push({
        test: /\.svg$/,
        loader: "vue-svg-loader"
      });
    }
 }

All 10 comments

Duplicate of #2302. See this comment for a working solution.

Please review the reproduction repo. It has the solution applied from #2302, but it still does not work.

vue-svg-loader should output a vue component, not a base64 string. The reason comment from #2302 works is because they are putting the base64 svg into img :src="here", but that's not what I'm trying to achieve.

With latest nuxt-edge I've sucessfully included vue-svg-loader with the following extension code:

extend(config) {
  config.module.rules.filter(r => r.test.toString().includes('svg')).forEach(r => { r.test = /\.(png|jpe?g|gif)$/ })
  config.module.rules.push({
    test: /\.svg$/,
    loader: "vue-svg-loader"
  })
}

I'll look if this code works for 1.4.2 as well. and report back.

UPDATE: It does

I have updated the reproduction repo, this still does not work for me. Svg is removed from url-loader test property, but somehow it still gets processed to base64, because I'm getting this error:

[Vue warn]: Invalid Component definition: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMCIgd2lkdGg9IjEwMCI+CiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNDAiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0icmVkIiAvPgo8L3N2Zz4g

found in

---> <Pages/index.vue> at pages/index.vue
       <Nuxt>
         <Default> at layouts/default.vue
           <Root>

Can you confirm the reproduction repo is working for you? Thanks!

it does fail because you apply the loader only client-side, not on both sides.

This will work out ;)

extend(config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: "pre",
          test: /\.(js|vue)$/,
          loader: "eslint-loader",
          exclude: /(node_modules)/
        });
      }
      config.module.rules
        .filter(r => r.test.toString().includes("svg"))
        .forEach(r => {
          r.test = /\.(png|jpe?g|gif)$/;
       });
      config.module.rules.push({
        test: /\.svg$/,
        loader: "vue-svg-loader"
      });
    }
 }

It does work now! For some reason I didn't really pay attention to if (isDev && isClient) and in my head it somehow evaluated to if (isServer && isClient), so I thought everything should work. Thanks for helping me solve this! I'll submit a pull request to vue-svg-loader documentation so other people wouldn't do the same mistake.

By the way, I'm not sure if doing

.forEach(r => {
  r.test = /\.(png|jpe?g|gif)$/;
})

is a good idea, there should be a way of removing just the svg part from test regex instead of replacing the whole query. Maybe this would work better?

.forEach(r => {
  r.test = new RegExp(r.test.source.replace(/\|?svg/gi, ""));
});

@FistMeNaruto You are welcome :relaxed:

About the replacement: It's hard to "correctly" replace it for an arbitrary query but it's still better than assigning the value. :ok_hand:

Maybe this regex would work better?

.forEach(r => {
  r.test = new RegExp(r.test.source.replace(/(svg\|)|(\|?svg)/gi, ''))
})

It would also remove svg when it someday would be the first in list.

@alanaasmaa You can customize your loaders by now (in nuxt-edge), which makes the strategy discussed here obsolete (see #3799)

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shyamchandranmec picture shyamchandranmec  路  3Comments

mikekidder picture mikekidder  路  3Comments

mattdharmon picture mattdharmon  路  3Comments

VincentLoy picture VincentLoy  路  3Comments

bimohxh picture bimohxh  路  3Comments