简体   繁体   中英

graphQL + gatsby: query a field that is Image or mp4

Have a gatsby blog to which I've added a cover image that is either an image (I want that to appear as a Gatsby Image) or mp4 (I want that to appear as html5 video).

The problem is, when I query this field (in my markdown posts, cover: x.mp4 or cover: x.jpg ), if it's an mp4 and it doesn't have a property of childImageSharp (error: TypeError: Cannot read property 'fluid' of null ).

My query looks like this:

  frontmatter {
    date(formatString: "YYYY")
    title
    cover {
      childImageSharp {
        fluid(maxWidth: 900) {
          ...GatsbyImageSharpFluid_noBase64
          ...GatsbyImageSharpFluidLimitPresentationSize
        }
      }
    }
  }

so my goal is to have some kind of JSX like:

{post.frontmatter.cover.childImageSharp && (
  <Img fluid={post.frontmatter.cover.childImageSharp.fluid} />
)}
{post.frontmatter.cover.childImageSharp ? '' : (
  <video src={post.frontmatter.cover} />
)}

any ideas?

The problem is, when I query this field (in my markdown posts, cover: x.mp4 or cover: x.jpg), if it's an mp4 and it doesn't have a property of childImageSharp (error: TypeError: Cannot read property 'fluid' of null).

The cover field will be a File node, so you won't be able to get the video src from it directly. If you just want access to the mp4 file (to put inside a video tag), you can query for its publicURL :

  frontmatter {
    date(formatString: "YYYY")
    title
    cover {
      extension
      publicURL

      childImageSharp {
        fluid(maxWidth: 900) {
          ...GatsbyImageSharpFluid_noBase64
          ...GatsbyImageSharpFluidLimitPresentationSize
        }
      }
    }
  }

Then in your component:

{cover.extension === 'mp4'
  ? <video src={cover.publicURL} />
  : <Img fluid={cover.childImageSharp.fluid} />
)}

Why you don't mix both methods?

{post.frontmatter.cover.childImageSharp ? <Img fluid={post.frontmatter.cover.childImageSharp.fluid} /> : <video src={post.frontmatter.cover} />}

Regardless of how you will manage it, I think that your idea is a good approach to achieve what you want. You'll render one component or another depending on your query so, it's efficient and clean.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM