Skip to content

Commit 4d26320

Browse files
floydnoelerquhart
authored andcommitted
Gatsby image w/preview compat (#122)
1 parent 2696ede commit 4d26320

File tree

6 files changed

+141
-34
lines changed

6 files changed

+141
-34
lines changed

gatsby-config.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ module.exports = {
55
plugins: [
66
'gatsby-plugin-react-helmet',
77
'gatsby-plugin-sass',
8+
{
9+
// keep as first gatsby-source-filesystem plugin for gatsby image support
10+
resolve: 'gatsby-source-filesystem',
11+
options: {
12+
path: `${__dirname}/static/img`,
13+
name: 'uploads',
14+
},
15+
},
816
{
917
resolve: 'gatsby-source-filesystem',
1018
options: {
@@ -24,7 +32,23 @@ module.exports = {
2432
{
2533
resolve: 'gatsby-transformer-remark',
2634
options: {
27-
plugins: [],
35+
plugins: [
36+
{
37+
resolve: 'gatsby-remark-relative-images',
38+
options: {
39+
name: 'uploads',
40+
},
41+
},
42+
{
43+
resolve: 'gatsby-remark-images',
44+
options: {
45+
// It's important to specify the maxWidth (in pixels) of
46+
// the content container as this plugin uses this as the
47+
// base for generating different widths of each image.
48+
maxWidth: 2048,
49+
},
50+
},
51+
],
2852
},
2953
},
3054
{

gatsby-node.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const _ = require('lodash')
22
const path = require('path')
33
const { createFilePath } = require('gatsby-source-filesystem')
4+
const { fmImagesToRelative } = require('gatsby-remark-relative-images')
45

56
exports.createPages = ({ actions, graphql }) => {
67
const { createPage } = actions
@@ -73,6 +74,7 @@ exports.createPages = ({ actions, graphql }) => {
7374

7475
exports.onCreateNode = ({ node, actions, getNode }) => {
7576
const { createNodeField } = actions
77+
fmImagesToRelative(node) // convert image paths for gatsby images
7678

7779
if (node.internal.type === `MarkdownRemark`) {
7880
const value = createFilePath({ node, getNode })

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
"dependencies": {
77
"bulma": "^0.7.0",
88
"gatsby": "^2.0.0",
9+
"gatsby-image": "^2.0.10",
910
"gatsby-plugin-netlify": "^2.0.0",
1011
"gatsby-plugin-netlify-cms": "^3.0.0",
1112
"gatsby-plugin-react-helmet": "^3.0.0",
1213
"gatsby-plugin-sass": "^2.0.1",
1314
"gatsby-plugin-sharp": "^2.0.5",
1415
"gatsby-remark-images": "^2.0.1",
16+
"gatsby-remark-relative-images": "^0.2.0",
1517
"gatsby-source-filesystem": "^2.0.1",
1618
"gatsby-transformer-remark": "^2.1.1",
1719
"gatsby-transformer-sharp": "^2.1.1",

src/components/Features.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import React from 'react'
22
import PropTypes from 'prop-types'
3+
import PreviewCompatibleImage from '../components/PreviewCompatibleImage'
34

45
const FeatureGrid = ({ gridItems }) => (
56
<div className="columns is-multiline">
67
{gridItems.map(item => (
7-
<div key={item.image} className="column is-6">
8+
<div key={item.text} className="column is-6">
89
<section className="section">
9-
<p className="has-text-centered">
10-
<img alt="" src={item.image} />
11-
</p>
10+
<div className="has-text-centered">
11+
<div
12+
style={{
13+
width: '240px',
14+
display: 'inline-block',
15+
}}
16+
>
17+
<PreviewCompatibleImage imageInfo={item.image} />
18+
</div>
19+
</div>
1220
<p>{item.text}</p>
1321
</section>
1422
</div>
@@ -19,7 +27,7 @@ const FeatureGrid = ({ gridItems }) => (
1927
FeatureGrid.propTypes = {
2028
gridItems: PropTypes.arrayOf(
2129
PropTypes.shape({
22-
image: PropTypes.string,
30+
image: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
2331
text: PropTypes.string,
2432
})
2533
),
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
import Img from 'gatsby-image'
4+
5+
const PreviewCompatibleImage = ({ imageInfo }) => {
6+
const imageStyle = { borderRadius: '5px' }
7+
const { alt = '', childImageSharp, image } = imageInfo
8+
9+
if (!!image && !!image.childImageSharp) {
10+
return (
11+
<Img style={imageStyle} fluid={image.childImageSharp.fluid} alt={alt} />
12+
)
13+
}
14+
15+
if (!!childImageSharp) {
16+
return <Img style={imageStyle} fluid={childImageSharp.fluid} alt={alt} />
17+
}
18+
19+
if (!!image && typeof image === 'string')
20+
return <img style={imageStyle} src={image} alt={alt} />
21+
22+
return null
23+
}
24+
25+
PreviewCompatibleImage.propTypes = {
26+
imageInfo: PropTypes.shape({
27+
alt: PropTypes.string,
28+
childImageSharp: PropTypes.object,
29+
image: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired,
30+
style: PropTypes.object,
31+
}).isRequired,
32+
}
33+
34+
export default PreviewCompatibleImage

src/templates/product-page.js

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Layout from '../components/Layout'
55
import Features from '../components/Features'
66
import Testimonials from '../components/Testimonials'
77
import Pricing from '../components/Pricing'
8+
import PreviewCompatibleImage from '../components/PreviewCompatibleImage'
89

910
export const ProductPageTemplate = ({
1011
image,
@@ -25,7 +26,13 @@ export const ProductPageTemplate = ({
2526
<div className="content">
2627
<div
2728
className="full-width-image-container margin-top-0"
28-
style={{ backgroundImage: `url(${image})` }}
29+
style={{
30+
backgroundImage: `url(${
31+
!!image.childImageSharp
32+
? image.childImageSharp.fluid.src
33+
: image
34+
})`,
35+
}}
2936
>
3037
<h2
3138
className="has-text-weight-bold is-size-1"
@@ -61,38 +68,32 @@ export const ProductPageTemplate = ({
6168
<div className="tile">
6269
<div className="tile is-parent is-vertical">
6370
<article className="tile is-child">
64-
<img
65-
style={{ borderRadius: '5px' }}
66-
src={main.image1.image}
67-
alt={main.image1.alt}
68-
/>
71+
<PreviewCompatibleImage imageInfo={main.image1} />
6972
</article>
7073
</div>
7174
<div className="tile is-parent">
7275
<article className="tile is-child">
73-
<img
74-
style={{ borderRadius: '5px' }}
75-
src={main.image2.image}
76-
alt={main.image2.alt}
77-
/>
76+
<PreviewCompatibleImage imageInfo={main.image2} />
7877
</article>
7978
</div>
8079
</div>
8180
<div className="tile is-parent">
8281
<article className="tile is-child">
83-
<img
84-
style={{ borderRadius: '5px' }}
85-
src={main.image3.image}
86-
alt={main.image3.alt}
87-
/>
82+
<PreviewCompatibleImage imageInfo={main.image3} />
8883
</article>
8984
</div>
9085
</div>
9186
</div>
9287
<Testimonials testimonials={testimonials} />
9388
<div
9489
className="full-width-image-container"
95-
style={{ backgroundImage: `url(${fullImage})` }}
90+
style={{
91+
backgroundImage: `url(${
92+
fullImage.childImageSharp
93+
? fullImage.childImageSharp.fluid.src
94+
: fullImage
95+
})`,
96+
}}
9697
/>
9798
<h2 className="has-text-weight-semibold is-size-2">
9899
{pricing.heading}
@@ -108,7 +109,7 @@ export const ProductPageTemplate = ({
108109
)
109110

110111
ProductPageTemplate.propTypes = {
111-
image: PropTypes.string,
112+
image: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
112113
title: PropTypes.string,
113114
heading: PropTypes.string,
114115
description: PropTypes.string,
@@ -118,12 +119,12 @@ ProductPageTemplate.propTypes = {
118119
main: PropTypes.shape({
119120
heading: PropTypes.string,
120121
description: PropTypes.string,
121-
image1: PropTypes.object,
122-
image2: PropTypes.object,
123-
image3: PropTypes.object,
122+
image1: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
123+
image2: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
124+
image3: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
124125
}),
125126
testimonials: PropTypes.array,
126-
fullImage: PropTypes.string,
127+
fullImage: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
127128
pricing: PropTypes.shape({
128129
heading: PropTypes.string,
129130
description: PropTypes.string,
@@ -166,12 +167,24 @@ export const productPageQuery = graphql`
166167
markdownRemark(id: { eq: $id }) {
167168
frontmatter {
168169
title
169-
image
170+
image {
171+
childImageSharp {
172+
fluid(maxWidth: 2048, quality: 100) {
173+
...GatsbyImageSharpFluid
174+
}
175+
}
176+
}
170177
heading
171178
description
172179
intro {
173180
blurbs {
174-
image
181+
image {
182+
childImageSharp {
183+
fluid(maxWidth: 240, quality: 64) {
184+
...GatsbyImageSharpFluid
185+
}
186+
}
187+
}
175188
text
176189
}
177190
heading
@@ -182,22 +195,46 @@ export const productPageQuery = graphql`
182195
description
183196
image1 {
184197
alt
185-
image
198+
image {
199+
childImageSharp {
200+
fluid(maxWidth: 526, quality: 92) {
201+
...GatsbyImageSharpFluid
202+
}
203+
}
204+
}
186205
}
187206
image2 {
188207
alt
189-
image
208+
image {
209+
childImageSharp {
210+
fluid(maxWidth: 526, quality: 92) {
211+
...GatsbyImageSharpFluid
212+
}
213+
}
214+
}
190215
}
191216
image3 {
192217
alt
193-
image
218+
image {
219+
childImageSharp {
220+
fluid(maxWidth: 1075, quality: 72) {
221+
...GatsbyImageSharpFluid
222+
}
223+
}
224+
}
194225
}
195226
}
196227
testimonials {
197228
author
198229
quote
199230
}
200-
full_image
231+
full_image {
232+
childImageSharp {
233+
fluid(maxWidth: 2048, quality: 100) {
234+
...GatsbyImageSharpFluid
235+
}
236+
}
237+
}
201238
pricing {
202239
heading
203240
description

0 commit comments

Comments
 (0)