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

Issue with loading SVG sprite #36

Closed
tk-o opened this issue Jan 14, 2018 · 6 comments
Closed

Issue with loading SVG sprite #36

tk-o opened this issue Jan 14, 2018 · 6 comments

Comments

@tk-o
Copy link

tk-o commented Jan 14, 2018

I'm trying to load an SVG file as a React component. I found a PR facebook/create-react-app#3718 by @iansu that solves the problem.

However there is an issue with reading the SVG file contents.

Issue
I have the following SVG file (it was generated by [svg-sprite]):(https://www.npmjs.com/package/svg-sprite)

<?xml version="1.0" encoding="UTF-8"?>
<svg width="0" height="0" style="position:absolute">
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="filter">
    <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
    <path d="M0 0h24v24H0z" fill="none" />
  </symbol>
</svg>

which is being imported as:
image
As you see the <svg /> element is empty.

Workaround
I was able to find a workaround to the above. All works fine if I add <defs /> element that includes <style /> element:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="0" height="0" style="position:absolute">
  <defs><style></style></defs>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="filter">
    <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
    <path d="M0 0h24v24H0z" fill="none" />
  </symbol>
</svg>

which returns a proper <svg /> element and its contents:
image

Expected scenario
The SVG example from Issue section should be loaded correctly (with its contents) without adding some extra tags.

@gregberge
Copy link
Owner

It is very strange. Thanks for reporting it.

@gregberge
Copy link
Owner

It was not a bug but a feature, it is removed by SVGO. I added an option to keep useless defs. See #42. Will be part of next release.

@tk-o
Copy link
Author

tk-o commented Jan 22, 2018

Perfect! Thank you :)

@gregberge
Copy link
Owner

@wawezz
Copy link

wawezz commented Jun 17, 2024

Same error loading sprite:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<symbol id="ah_icon_alert" viewBox="0 0 983 1024">
<path d="M493.556 205.519l331.457 591.956h-662.913l331.457-591.956zM529.293 143.589c-15.639-27.931-55.837-27.931-71.475 0l-366.397 654.353c-15.288 27.304 4.447 60.973 35.739 60.973h732.792c31.293 0 51.028-33.669 35.738-60.973l-366.395-654.353z"/>
<path d="M522.482 408.365v185.874c0 16.966-13.754 30.72-30.72 30.72-16.97 0-30.72-13.754-30.72-30.72v-185.874c0-16.966 13.75-30.72 30.72-30.72 16.966 0 30.72 13.754 30.72 30.72z"/>
<path d="M456.95 701.223c0-19.227 15.585-34.816 34.816-34.816 19.227 0 34.816 15.589 34.816 34.816 0 19.231-15.589 34.816-34.816 34.816-19.231 0-34.816-15.585-34.816-34.816z"/>
</symbol>
</svg>

result:

<svg xmlns="http://www.w3.org/2000/svg"></svg>

here is config:

  webpack(config) {
    // Grab the existing rule that handles SVG imports
    const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'))

    config.module.rules.push(
      // Reapply the existing rule, but only for svg imports ending in ?url
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: /url/ // *.svg?url
      },
      // Convert all other *.svg imports to React components
      {
        test: /\.svg$/i,
        issuer: fileLoaderRule.issuer,
        resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] }, // exclude if *.svg?url
        use: ['@svgr/webpack']
      }
    )

    // Modify the file loader rule to ignore *.svg, since we have it handled now.
    fileLoaderRule.exclude = /\.svg$/i

    return config
  }

@wawezz
Copy link

wawezz commented Jun 17, 2024

Same error loading sprite:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<symbol id="ah_icon_alert" viewBox="0 0 983 1024">
<path d="M493.556 205.519l331.457 591.956h-662.913l331.457-591.956zM529.293 143.589c-15.639-27.931-55.837-27.931-71.475 0l-366.397 654.353c-15.288 27.304 4.447 60.973 35.739 60.973h732.792c31.293 0 51.028-33.669 35.738-60.973l-366.395-654.353z"/>
<path d="M522.482 408.365v185.874c0 16.966-13.754 30.72-30.72 30.72-16.97 0-30.72-13.754-30.72-30.72v-185.874c0-16.966 13.75-30.72 30.72-30.72 16.966 0 30.72 13.754 30.72 30.72z"/>
<path d="M456.95 701.223c0-19.227 15.585-34.816 34.816-34.816 19.227 0 34.816 15.589 34.816 34.816 0 19.231-15.589 34.816-34.816 34.816-19.231 0-34.816-15.585-34.816-34.816z"/>
</symbol>
</svg>

result:

<svg xmlns="http://www.w3.org/2000/svg"></svg>

here is config:

  webpack(config) {
    // Grab the existing rule that handles SVG imports
    const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'))

    config.module.rules.push(
      // Reapply the existing rule, but only for svg imports ending in ?url
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: /url/ // *.svg?url
      },
      // Convert all other *.svg imports to React components
      {
        test: /\.svg$/i,
        issuer: fileLoaderRule.issuer,
        resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] }, // exclude if *.svg?url
        use: ['@svgr/webpack']
      }
    )

    // Modify the file loader rule to ignore *.svg, since we have it handled now.
    fileLoaderRule.exclude = /\.svg$/i

    return config
  }

Also I have try to load simple svg, all working correct

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