Gatsby: Inline SVG from Contentful

Created on 10 Jul 2018  Â·  17Comments  Â·  Source: gatsbyjs/gatsby

What's the best and easiest way to inline an SVG sourced from Contentful?

What I've been doing so far is something like

<img src={icon.file.url} alt={icon.title} />

which has the considerable drawback that it doesn't allow for outside control of the SVG, i.e. I can't change its fill color, hover state, etc.

stale? question or discussion

Most helpful comment

For anyone who is looking an answer like I was. There is a library from react https://github.com/gilbarbara/react-inlinesvg and this can convert svg served remotely to inline-svgs.

All 17 comments

I may be wrong but i think you can use it like this

<svg viewBox="0 0 193 57">
  <use xlink:href="theurlto.svg"></use>
</svg>

@porfirioribeiro Thanks for the quick reply! I tried your suggestion. I had to replace xlink:href with React's xLinkHref as recommended in this stackoverflow answer for it to compile. Problem is, the SVGs don't show up. I just get white space. Not sure what the problem is. I thought it might be that the <use> tag inside <svg> has zero height and width which the Chrome inspector confirmed. But I was unable to change that even by setting explicit values in the dev tools.

Yeah right, i copied from the generated html not from the react source :no_good_man:

Well i am using this for sprites width svg's symbols but i tough it would work with the full svg.

By the way, if the only thing you want is a simple color change, you can put fill="currentColor" and then set the css color of the parent.

Are your sprites coming from Contentful? Maybe it is related to the source rather than whether it's a full or a sprite svg.

Nop, mine are local using svg-sprite-loader so yeah, it's a diferent story :-1:
https://css-tricks.com/svg-use-with-external-reference-take-2/

Very interested in this topic as well. Working with the Netlify CMS that has certain content in yml files, so getting a generic source to an asset I'd like to inline is difficult since Webpack normally expects you to import this content at the top of the file.

Try gatsby-plugin-svgr, which transforms svg files into components for easy inline rendering.

CRA is now released as 2.0 and supports that out of the box using react-scripts:

https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-svgs

Should Gatsby support this too – as an official plugin?

Agree this would be a nice source transformation. Inlining is difficult from headless CMSes, I'm having this problem with Wordpress right now. I would expand this topic to something more like "Inlining external SVG"

Even if it were <img src={icon.file.url} alt={icon.title} /> --> fetch --> <svg>...</svg> while maintaining style declarations, it would be useful.

Maybe this?
https://www.npmjs.com/package/img-svg-inline-loader

@KyleAMathews: any thoughts here?

Old issues will be closed after 30 days of inactivity. This issue has been quiet for 20 days and is being marked as stale. Reply here or add the label "not stale" to keep this issue open!

Same issue here. I am getting various colored svgs from a headless WordPress. I am currently using publicURL from graphql but later realized I will need to manipulate the colors of these svg icons. My code is like <object data={svgPublicURL} type="image/svg+xml" />.

I have searched through and found something like image-webpack-loader but I think it will require my to import svg file at the beginning. It will be super handy if we can have a choice to "Inlining external SVG" like @braco mentioned.

For anyone who is looking an answer like I was. There is a library from react https://github.com/gilbarbara/react-inlinesvg and this can convert svg served remotely to inline-svgs.

@PoppinMic Hi!

I tried to use react-inlinesvg, but I got the following error Access has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Maybe you know how to fix it?

What if you try to use webpack require.context for inline svg?

For example:

// icon.js
import React from "react"

const Icon = ({ filename, classname }) => {
  const req = require.context(`../../images/icons`, true, /\.svg$/)
  const IconTag = req(`./${filename}.svg`)

  return <IconTag className={classname} />
}

export default Icon
// social.js
import React from "react"
// ...
import Icon from "../icon"

const Social = () => {
 // ...
  return (
    <ul className={st.social}>
      {data.allSocialItemsJson.edges.map(item => (
        <li className={st.social__item} key={item.node.name}>
          <a
            target="_blank"
            rel="noopener noreferrer"
            href={item.node.url}
            className={st.social__link}
          >
            <Icon
              filename={`social/${item.node.name}`}
              classname={st.social__icon}
            />
          </a>
        </li>
      ))}
    </ul>
  )
}

export default Social

Folder structure:

.
├── images
│   ├── icons
│   │   ├── social
│   │   │   ├── facebook.svg
│   │   │   ├── medium.svg
│   │   │   ├── telegram.svg
│   │   │   └── twitter.svg

@yaroslav-perec Hi, I think your problem is realted to general CORS issues. Google the keyword CORS. This should config on your server side

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.

Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community!

@in-in I've noticed that importing via require.context creates copy of the context in each chunk. Using webpack-bundle-analyzer I can see that assets/icons/flags are duplicated:

image

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KyleAMathews picture KyleAMathews  Â·  3Comments

timbrandin picture timbrandin  Â·  3Comments

ghost picture ghost  Â·  3Comments

mikestopcontinues picture mikestopcontinues  Â·  3Comments

kalinchernev picture kalinchernev  Â·  3Comments