Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow optional sharp image in graphql gatsby?

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.

like image 976
Joe Methven Avatar asked Feb 19 '20 15:02

Joe Methven


People also ask

Can you use Gatsby with sharp?

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.

How does GraphQL work with Gatsby?

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.

What is Gatsby-plugin-sharp and how to use it?

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.

What is the Gatsby-image library?

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.


Video Answer


1 Answers

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!

like image 50
Joe Methven Avatar answered Oct 16 '22 18:10

Joe Methven