Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inlining SVGs #13

Closed
chrisjansky opened this issue Mar 3, 2020 · 3 comments
Closed

Inlining SVGs #13

chrisjansky opened this issue Mar 3, 2020 · 3 comments

Comments

@chrisjansky
Copy link

Hey,

Thanks for a great plugin, getting it up and running with nuxt was a breeze. How do you inline SVGs without resorting to another loader (which causes a Webpack config conflict error, as stated in the README)?

Thanks!

@geeogi
Copy link
Owner

geeogi commented Mar 3, 2020

You can use SVGs straightaway in a standard HTML template e.g. <svg>...</svg>. You just need to save your SVGs as .vue components e.g.

<template>
    <svg width="100" height="100">
      <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
    </svg>
</template>

Alternatively, if you want to save them as .svg files and import them as components inline then you can add a custom webpack config in nuxt.config.js to handle this e.g. if you follow this gist everything should work except you'll need to update the following to remove the existing SVG rule:

// Remove SVG from default rules
config.module.rules.forEach(rule => {
  if (rule.test.toString() === "/.(svg|gif)$/i") {
    rule.test = /\.(gif)$/i;
  }
});

It might be fiddly though. Sorry this functionality isn't supported out-of-the-box with this module.

@tettoffensive
Copy link

@chrisjansky I made a module/svgHtmlLoader.js which looks very similar to nuxt-responsive-loader.
But you need to make sure to include them in this order in your nuxt.config.js

modules: [
    'nuxt-responsive-loader',
    '@/modules/svgHtmlLoader',

and the loader:

const DEFAULT_SVG_LOADER_OPTIONS = {
  minimize: true,
  attrs: ['div:v-html'],
};

const setupSvgImageLoader = userOptions => config => {
  // Find the existing webpack loader responsible for svgs (and other images)
  const existingImageLoader = config.module.rules.find(
    rule => rule.test.test('.svg')
  );

  /* If the image loader rule has been removed or edited then we cannot continue.
   ** It is not clear how to update the webpack rules.
   ** The user should define a custom webpack configuration.
   */
  if (!existingImageLoader) {
    throw new Error(
      [
        'svgHtmlLoader: Could not find the existing image loader rule.',
        ' The webpack config has been edited, perhaps by another Nuxt module.',
        ' To resolve this error try placing this module first in your Nuxt modules array',
        ' or use a custom webpack configuration instead.'
      ].join('')
    )
  }
  
  /* Update the loader so it's no longer respo∏nsible for svg files */
  if (existingImageLoader) {
    existingImageLoader.test = /\.(gif)$/i;
  }

  /* Add the new loader rule */
  config.module.rules.push({
      test: /\.(svg)$/,
      loader: 'html-loader',
      options: userOptions || DEFAULT_SVG_LOADER_OPTIONS,
  });
}

export default function svgHtmlLoader () {
  const { svgHtmlLoader: userOptions } = this.options
  this.extendBuild(setupSvgImageLoader(userOptions))
}

@chrisjansky
Copy link
Author

Thank you both @geeogi and @tettoffensive!

I've ended up importing .vue files per @geeogi suggestion, but might come to implement the latter if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants