I am trying to make a splash image for my website using graphql and gatsby Image. I am trying to use childImageSharp fluid, hoping to ve able to serve different size versions of the Image for different client devices.
Here the code:
import React from 'react'
import { Link, graphql } from 'gatsby'
import './style.scss'
export default ({data}) => (
<div className="full" style={{background:data.file.childImageSharp.fluid}}>
<div className="container">
<div className="row clearfix">
<div style={{padding: "0 0 400px 0"}}>
<div className="col-xs-5 line">
</div>
<div className="col-xs-2 logo text-center"></div>
<div className="col-xs-5 line">
</div>
</div>
</div>
</div>
</div>
)
export const query = graphql`
query{
file(relativePath:{eq:"splash.jpg"}){
childImageSharp{
fluid{
...GatsbyImageSharpFluid
}
}
}
}
`
What i am getting is the error below:

When I query the file with graphql, the file is located with no problems.
here my gatsby-node.js file:
const each = require('lodash/each')
const Promise = require('bluebird')
const path = require('path')
const PostTemplate = path.resolve('./src/templates/index.js')
const ProductTemplate =path.resolve('./src/templates/ProductDetail/index.js')
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
resolve(
graphql(
`
{
allFile(filter: { extension: { regex: "/md|js|jpg/" } }, limit: 1000) {
edges {
node {
id
name: sourceInstanceName
path: absolutePath
remark: childMarkdownRemark {
id
frontmatter {
layout
path
}
}
}
}
}
allContentfulMarka(filter:{name:{eq:"Bestpet"},node_locale:{eq:"tr-TR"}}){
edges{
node{
products: _r_nler{
name
id
}
}
}
}
}
`
).then(({ errors, data }) => {
if (errors) {
console.log(errors)
reject(errors)
}
// Create blog posts & pages.
const items = data.allFile.edges
console.log(items)
const posts = items.filter(({ node }) => /posts/.test(node.name))
each(posts, ({ node }) => {
if (!node.remark) return
const { path } = node.remark.frontmatter
createPage({
path,
component: PostTemplate,
})
})
const products = data.allContentfulMarka.edges[0].node.products
console.log(products)
each(products, (index, product ) => {
console.log("===>"+index.id)
const path = `/product-tr/${index.id}`
createPage({
path,
component: ProductTemplate,
context:{
productId: index.id
},
})
})
const pages = items.filter(({ node }) => /page/.test(node.name))
each(pages, ({ node }) => {
if (!node.remark) return
const { name } = path.parse(node.path)
const PageTemplate = path.resolve(node.path)
createPage({
path: name,
component: PageTemplate,
})
})
})
)
})
}
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
alias: {
components: path.resolve(__dirname, 'src/components'),
templates: path.resolve(__dirname, 'src/templates'),
scss: path.resolve(__dirname, 'src/scss'),
},
},
})
}
Sorry I have been bugging you all, but this is my first project thanks for the understanding in advance.
@ergunpp don't worry, that's why we are here, to help out as much as we can. From what i'm reading from your code you it looks like you have a issue there. You're injecting the image into the style property of the div.
Namely:
export default ({data}) => (
<div className="full" style={{background:data.file.childImageSharp.fluid}}><---here
<div className="container">
<div className="row clearfix">
<div style={{padding: "0 0 400px 0"}}>
<div className="col-xs-5 line">
</div>
<div className="col-xs-2 logo text-center"></div>
<div className="col-xs-5 line">
</div>
</div>
</div>
</div>
</div>
)
Try and change your code to something like this:
import React from 'react'
import { Link, graphql } from 'gatsby'
import Img from 'gatsby-image'
import './style.scss'
export default ({data}) => (
<div className="full">
<div className="container">
<div className="row clearfix">
<div style={{padding: "0 0 400px 0"}}>
<div className="col-xs-5 line">
<Img fluid={data.childImageSharp.fluid} /><---injects the content coming from the graphql query you created to the gatsby image component
</div>
<div className="col-xs-2 logo text-center"></div>
<div className="col-xs-5 line">
</div>
</div>
</div>
</div>
</div>
)
Feel free to provide some feedback if the issue is resolve.
Also you can read up more on images and gatsby in here or this great article in here
To add to what @jonniebigodes said, if you need to use the image via CSS you simply have to wrap it in a url() and use the src field:
//...
<div className="full" style={{
backgroundImage: `url("${data.file.childImageSharp.fluid.src}")`
}}>
// ...
However, using the gatsby-image component is definitely preferable if possible, since it renders responsive images by default which isn't possible at all with CSS background-image.
See this Stack Overflow answer for when you should use CSS background-images or HTML <img> elements (or gatsby-image in this case).
I think thats not the only problem. I changed as suggested to:
import React from 'react'
import { Link, graphql } from 'gatsby'
import Img from 'gatsby-image'
import './style.scss'
export default ({data}) => (
<div className="full">
<div className="container">
<div className="row clearfix">
<div style={{padding: "0 0 400px 0"}}>
<div className="col-xs-5 line">
<Img fluid={data.file.childImageSharp.fluid} />
</div>
<div className="col-xs-2 logo text-center"></div>
<div className="col-xs-5 line">
</div>
</div>
</div>
</div>
</div>
)
export const query = graphql`
query{
file(relativePath:{eq:"splash.jpg"}){
childImageSharp{
fluid{
base64
}
}
}
}
`
But I am still getting the error:
×
←→1 of 4 errors on the page
TypeError: Cannot read property 'file' of undefined
_default
src/components/Splash/index.js:12
9 | <div className="row clearfix">
10 | <div style={{padding: "0 0 400px 0"}}>
11 | <div className="col-xs-5 line">
> 12 | <Img fluid={data.file.childImageSharp.fluid} />
13 | </div>
14 | <div className="col-xs-2 logo text-center"></div>
15 | <div className="col-xs-5 line">
View compiled
▶ 23 stack frames were collapsed.
(anonymous function)
/home/ec2-user/environment/bootstrap/.cache/app.js:56
53 | loader.getResourcesForPathname(window.location.pathname).then(() => {
54 | let Root = hot(module)(preferDefault(require(`./root`)))
55 | domReady(() => {
> 56 | renderer(<Root />, rootElement, () => {
57 | apiRunner(`onInitialClientRender`)
58 | })
59 | })
I got it to work with staticquery. No problems.
Thank you so much for all the help.
Glad you were able to solve the problems! Always happy to help.
@jgierer12 I was looking for the graphql background image syntax for ages. Thank you so much.
Most helpful comment
To add to what @jonniebigodes said, if you need to use the image via CSS you simply have to wrap it in a
url()and use thesrcfield:However, using the
gatsby-imagecomponent is definitely preferable if possible, since it renders responsive images by default which isn't possible at all with CSSbackground-image.See this Stack Overflow answer for when you should use CSS
background-images or HTML<img>elements (orgatsby-imagein this case).