I typically have frontmatter that will have an array of objects, inside each object will be an image which will reference a string of a file relative to the markdown file.
The problem is, the array could sometimes be empty, meaning graphql will have to work out what the schema is by setting all the values to non-null, I have been able to do this with simple types such as strings using Gatsby's createSchemaCustomization
, but I want to be able to declare a string that references an image to use Image Sharp (so gatsby-transformer-sharp can compress the image before the component receives it).
It doesn't seem like anywhere on the Gatsby documentation or image sharp plugin that there is a schema type for this.
I tried using File!
as a type which works when the array is empty but when you actually try to reference real images it simply returns { image: childImageSharp: null }
meaning gatsby-transformer-sharp doesn't run on them like it does when File!
isn't decalared.
Below is how my schema has been declared:
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type MarkdownRemark implements Node {
frontmatter: Frontmatter
}
type Frontmatter {
features: [Feature!]!
}
type Feature {
title: String!
description: String!
image: File!
}
`;
createTypes(typeDefs);
};
This is my graphql query:
export const query = graphql`
query HomeQuery($path: String!) {
markdownRemark(frontmatter: { path: { eq: $path } }) {
html
frontmatter {
features {
title
description
image {
childImageSharp {
fluid(maxWidth: 800) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
`;
And my markdown file which returns the array of objects of features, image
being the string which should create a fluid image sharp object.
---
path: '/'
features:
- title: Barns
description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
image: features-001.png
- title: Private Events
description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
image: features-002.png
- title: Food and Drinks
description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
image: features-003.png
- title: Spa
description: Praesent commodo cursus magna vel scelerisque nisl consectetur et. Nullam id dolor id nibh ultricies vehicula ut id elit.
image: features-004.png
---
As an overview, as soon as I remove the File!
on the createSchemaCustomization
all the images show up, but the build will break as soon as the array is empty.
However, with Gatsby, we can leverage the power of Sharp to get the best performance with a little setup and a rich toolset. In this article, we’ll take a look at the gatsby-image component and how it can simplify the process of using images in various scenarios. The steps in this guide assume you have a working Gatsby project.
This is possible because in GraphQL, you query against a schema that is the representation of your available data. Don’t worry about where the schema comes from right now, Gatsby takes care of organizing all of your data for you and making it discoverable with a tool called GraphiQL.
gatsby-plugin-sharp is a low-level helper that powers the connections between Sharp and gatsby-image. It also exposes several image processing functions. gatsby-transformer-sharp facilitates the creation of multiples images of the right sizes and resolutions. Now that we’re set up, we can start working with images in our site.
Gatsby Image is a library that uses the Sharp image library under the hood and does a lot of optimization work for you. To get started, let's install what we'll need: This will install the gatsby-image library as well as two plugins we'll be using throughout the course.
After months of on and off searching I managed to work it out, I was correct by using the File
type, the reason it was returning empty on images that did exist is that I was missing the ever-special directive @fileByRelativePath
.
For all those that are struggling with this, you must have an exported function called createShcemaCustomization in your gatsby-node.js
, from here you must configure your frontmatter properties that you would like to provide the non-null values on.
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions;
const typeDefs = [
`type MarkdownRemark implements Node {
frontmatter: Frontmatter
}`,
`type Frontmatter @infer {
about_hero_slides: [File!]! @fileByRelativePath,
about_title: String,
about_text: String,
about_images: [File!]! @fileByRelativePath,
}`,
];
createTypes(typeDefs);
};
Once I added in @infer
on the Frontmatter
type and @fileByRelativePath
to each File property it instantly resolved any images, and all images that didn't exist would simply return null instead of throwing an error!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With