Parcel: How to make react svg use xlinkHref work ?

Created on 3 Nov 2018  ·  6Comments  ·  Source: parcel-bundler/parcel

❔ Question

How to make svg sprites work in react+parcel ?

🔦 Context

Can't load svg symbols inside a sprite.

💻 Code Sample

Using openicons. For reference, just a couple of icons.

icons.svg

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="audio" viewBox="0 0 8 8">
  <path d="M3 0v1h4v5h-4v1h5v-7h-5zm1 2v1h-4v1h4v1l2-1.5-2-1.5z"></path>
</symbol>
<symbol id="account-logout" viewBox="0 0 8 8">
  <path d="M3 0v1h4v5h-4v1h5v-7h-5zm-1 2l-2 1.5 2 1.5v-1h4v-1h-4v-1z"></path>
</symbol>
</defs>
</svg>

icon.js

import React from 'react'
import './icons.svg'

const Icon = props => (
    <svg className={`icon icon-${props.name}`}>
        <use xlinkHref={`#${props.name}`} />
    </svg>
)

export default Icon

I've also tried

<use xlinkHref={`./icons.svg#${props.name}`} />

app.js

import React, { Component } from 'react'

import './app.css'
import logo from './logo.svg'
import Icon from './icon'

export default class App extends Component {
    render() {
        return (
            <div className="App">
                <h1>This works!!!!</h1>
                <img src={logo} className="App-logo" alt="logo" />
                <Icon name="audio" />
            </div>
        )
    }
}

This is the dom result

screen shot 2018-11-03 at 10 14 27

But the icon doesn't show.

I've changed width and height, still no go.

Seems like it can't find icons.svg

Note that if I import an simple svg and use it as img src, it works.

🌍 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.10.3
| Node | v8.12.0
| npm/Yarn | 6.4.1
| Operating System | macOS 10.13.5

Question

Most helpful comment

Got it working !!

import React from 'react'

import icons from './icons.svg'

const Icon = props => {
    return (
        <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
            className={`icon icon-${props.name}`}
        >
            <use xlinkHref={`${icons}#${props.name}`} />
        </svg>
    )
}

export default Icon

All 6 comments

Got it working !!

import React from 'react'

import icons from './icons.svg'

const Icon = props => {
    return (
        <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
            className={`icon icon-${props.name}`}
        >
            <use xlinkHref={`${icons}#${props.name}`} />
        </svg>
    )
}

export default Icon

Thanks! This helped me get it working too!

Got it working !!

import React from 'react'

import icons from './icons.svg'

const Icon = props => {
  return (
      <svg
          xmlns="http://www.w3.org/2000/svg"
          xmlnsXlink="http://www.w3.org/1999/xlink"
          className={`icon icon-${props.name}`}
      >
          <use xlinkHref={`${icons}#${props.name}`} />
      </svg>
  )
}

export default Icon

What did you change?

Got it working !!

import React from 'react'

import icons from './icons.svg'

const Icon = props => {
    return (
        <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
            className={`icon icon-${props.name}`}
        >
            <use xlinkHref={`${icons}#${props.name}`} />
        </svg>
    )
}

export default Icon

What did you change?

add attr to svg - xmlnsXlink="http://www.w3.org/1999/xlink"

Changes to Icon component:

Import statement changed:
import icons from './icons.svg'

svg attributes added:
xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"

use tag's attribute altered to include the 'icons' import reference (make sure to reinsert backticks):
xlinkHref={${icons}#${props.name}}

Really helpful, thank you.
Any configuration we need to make on build/production?

Was this page helpful?
0 / 5 - 0 ratings