Hi, I've got a question how can I send SVG images as props?
If I do this I can display the image without any problem.
import ihtml from '../images/html5.svg'
const Skill = () => (
<div>
<img src={ihtml} alt=""/>
</div>
)
But I can't display an image as a prop like this :
import ihtml from '../images/html5.svg'
const Skill = (props) => (
<div>
{
props.skillNames.map((skillName, index) => {
return (
<div key={shortid.generate()}>
// the value of skillName.icon is ihtml
<img src={skillName.icon} alt=""/>
</div>
)
})
}
</div>
)
Any idea of how can I display images as props?
Thanks
Are there any errors? Either in terminal running gatsby build/develop or in browser? What is result of using your second code snippet?
Are there any errors?
No
Either in the terminal running, gatsby build/develop or in the browser?
gatsby develop
What is the result of using your second code snippet?
<img src="ihtml" alt="">
@Alfrex92 i've picked up on your issue and it looks like there's a bit of confusion regarding on how Gatsby handles assets.
By looking at your code, it looks like Gatsby and webpack will not "understand" and resolve the import of the assets you want.
You can avoid this through a couple of ways:
static folder approach, more on that issue heregatsby-source-filesystem plugin, coupled with a graphql query to fetch the contents needed.Below will be demonstrated both approaches.
This are based on a new Gatsby site, created with the hello world starter.
For the static folder approach here are the steps i took and code:
After the setup process of the template is complete, created the folder and grabbed a couple of svg files into it. Which originates the following structure:

After that i've created a component named Skill under src/components with the following code:
import React from 'react'
import uuid from 'uuid'
import { withPrefix } from 'gatsby';
const Skill = props => {
const { skillNames } = props
return (
<div>
{skillNames.map(item => {
return (
<div key={`svg_image_container${uuid.v4()}`}>
<img
key={`svg_image_${uuid.v4()}`}
src={withPrefix(item.icon)}
alt={item.title}
/>
</div>
)
})}
</div>
)
}
export default Skill
As you can see it's almost identical to the one you have, the only exception is uuid package that i've added to generate a unique uuid for the keys.
Also the withPrefix import that will handle the "relativity" of the files.
index.js file under pages to the following:import React from 'react'
import Skill from '../components/Skill'
export default () => {
const svgInfo = [
{
icon: './images/beacon.svg',
title: 'beacon',
},
{
icon: './images/osi.svg',
title: 'osi',
},
{
icon: './images/pencil.svg',
title: 'pencil',
},
{
icon: './images/semweb.svg',
title: 'semweb',
},
{
icon: './images/star.svg',
title: 'star',
},
{
icon: './images/sync.svg',
title: 'sync',
},
{
icon: './images/unicode.svg',
title: 'unicoder',
},
{
icon: './images/vnu.svg',
title: 'vnu',
},
{
icon: './images/vote.svg',
title: 'voting',
},
{
icon: './images/whatwg.svg',
title: 'what',
},
{
icon: './images/why.svg',
title: 'why',
},
{
icon: './images/wireless.svg',
title: 'wireless',
},
]
return <Skill skillNames={svgInfo} />
}
As the static folder exists and is populated when each and every item of the array is iterated and rendered, Gatsby will understand the file location and show you the contents, as you can see below:

To achieve the same result, but this time with the gatsby-source-filesystem plugin like i said above, some changes are needed:
gatsby-source-filesystem.gatsby-config.js file to configure the plugin, based on the information you've supplied it would look like something like this:module.exports = {
siteMetadata: {
title: `svg images as props`,
description: `This barebones site demonstrates how to add svg images`,
},
plugins: [{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.app/offline
// 'gatsby-plugin-offline',
],
}
Copied over the svg files to the folder src/images, as you can see below

Created a new component named Skill-Graphql for this case to diferentiate it, with the following code:
import React from 'react'
import uuid from 'uuid'
const SkillGraphql = props => {
const { skillNames } = props
return (
<div>
{skillNames.map(item => {
return (
<div key={`svg_image_container${uuid.v4()}`}>
<img
key={`svg_image_${uuid.v4()}`}
src={item.node.publicURL}
alt={`svg_${item.node.publicURL}`}
/>
</div>
)
})}
</div>
)
}
export default SkillGraphql
And finally a new page with the following code:
import React from 'react';
import { graphql } from "gatsby"
import SkillGraphql from '../components/Skill-Graphql'
const graphqlSourcePage=({ data })=>{
return (
<SkillGraphql skillNames={data.allFile.edges}/>
)
}
export const query=graphql`
query {
allFile(filter: {extension: {eq: "svg"}}) {
edges {
node {
publicURL
}
}
}
}
`;
export default graphqlSourcePage
As you can see the svg are loaded if i head onto page-2(file was called that, but the export is graphqlSourcePage), i'm presented with the following:

Also sorry for the svg shown in the images not being resized, forgot about it.
Hope i could shed some light on your issue with this rather extensive comment.
Feel free to provide feedback.
@jonniebigodes thank you sooo much for the detailed explanation. I understand it perfectly, I appreciated it =D
It is working.
I have one more question. One of the features that I like most about Gatsby is that automatically converts my img to data URI. With these two methods that you explained to me my img are not being converted to data URI. Is there any way where I can pass images as props and automatically converted it to data URI?
*As feedback, might be a good idea to add your explanation in this page. It was clear and easy to understand, I am sure that someone else will have the same question.
https://www.gatsbyjs.org/docs/adding-images-fonts-files/
@Alfrex92 No need to thank, i'm glad i could help you out and shed some insights to answer your issue. To answer your question regarding data uris, out of the box no. you can't. For that to work you would have to open each file, convert it to base64 format, escape it's content and suplly it to the <img/> element.
What you might be accustomed to see with gatsby and the images being shown as data uris, is that
gatsby-image component which relies on gatsby-transformer-sharp and gatsby-plugin-sharp handles that for you, it creates the traced image as a svg behind the scenes and lets you use it as so. Now here's the thing, that will only work for images like .jpg or .png for instance. For svgs it will not work, as this case the images are vector files and they don't need diferent sizes, they can scale indefinitely without loss of quality.
Regarding your second item, the feedback. If you want to do it, contribute to the documentation with this addition, i'm more than happy that you do it, grab the explanation i've provided, let me know and i'll set up a github repo with the code i've used for your issue and proceed from there. Sounds good?
I got it, thanks for the explanation :D
@Alfrex92 Once again, no need to thank, i'm glad i could help. Going to close this issue as it's answered. Once again, if you're willing to make that addition to the documentation let me know.
Most helpful comment
@Alfrex92 i've picked up on your issue and it looks like there's a bit of confusion regarding on how Gatsby handles assets.
By looking at your code, it looks like Gatsby and webpack will not "understand" and resolve the import of the assets you want.
You can avoid this through a couple of ways:
staticfolder approach, more on that issue heregatsby-source-filesystemplugin, coupled with a graphql query to fetch the contents needed.Below will be demonstrated both approaches.
This are based on a new Gatsby site, created with the hello world starter.
For the
staticfolder approach here are the steps i took and code:After the setup process of the template is complete, created the folder and grabbed a couple of svg files into it. Which originates the following structure:

After that i've created a component named
Skillundersrc/componentswith the following code:As you can see it's almost identical to the one you have, the only exception is
uuidpackage that i've added to generate a unique uuid for the keys.Also the
withPrefiximport that will handle the "relativity" of the files.index.jsfile underpagesto the following:As the static folder exists and is populated when each and every item of the array is iterated and rendered, Gatsby will understand the file location and show you the contents, as you can see below:

To achieve the same result, but this time with the
gatsby-source-filesystemplugin like i said above, some changes are needed:gatsby-source-filesystem.gatsby-config.jsfile to configure the plugin, based on the information you've supplied it would look like something like this:Copied over the svg files to the folder

src/images, as you can see belowCreated a new component named
Skill-Graphqlfor this case to diferentiate it, with the following code:And finally a new page with the following code:
As you can see the svg are loaded if i head onto

page-2(file was called that, but the export is graphqlSourcePage), i'm presented with the following:Also sorry for the svg shown in the images not being resized, forgot about it.
Hope i could shed some light on your issue with this rather extensive comment.
Feel free to provide feedback.