Gatsby: How can I use a childImageSharp node with an allMarkdownRemark node? [Netlify Related]

Created on 24 Sep 2018  路  6Comments  路  Source: gatsbyjs/gatsby

Summary

Hi. I am trying to use gatsby-image with my gatsby + netlify project. I have the following setup:

  • all images are uploaded into a /static/img folder

  • through netlify, a user can create a markdown file in /src/photos/ which references the file in the static folder and includes some tags in the markdown frontmatter. An example cat.md would look like:

---
title: Cat
image: /img/cat.png
tags:
  - bengal
  - cat
---

  • I can query for all of the markdown files in the /src/photos folder and grab the path to the image, but I cannot grab a childImageSharp node of the referenced image. I have included the /static/img folder in my gatsby-config.js using gatsby-source-filesystem, but I cannot figure out how to "connect" these two nodes. I tried to use the approach in this related issue, but I was not able to get it to work.

Any ideas on how I can accomplish this? It seems like I need to hook into the onCreateNode function in my gatsby-node.js file somehow with createNodeField or createParentChildLink, but I can't figure out the trick to making this work.

Relevant information

My repo: https://github.com/maxcrane/ross-crane-site

stale? question or discussion

Most helpful comment

I thought I did, but I think I may have gotten the relative path incorrect the first time. I retried and it worked! Thank you for mentioning that specific comment! What I did was similar:

gatsby-node.js

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark` && node.frontmatter.image) {
      const path = `../../static${node.frontmatter.image}`;

       createNodeField({
          node,
          name: 'image',
          value: path
       });
}

graphql query

query PhotosPage {
        allMarkdownRemark(limit: 1000, filter: { fileAbsolutePath: {regex : "\/photos/"} }) {
           edges {
              node {
                 frontmatter {
                     tags
                     image
                   }
                   fields {
                        image {
                         childImageSharp {
                           fluid(maxWidth: 2000, quality: 100) {
                              ...GatsbyImageSharpFluid
                           }
                         }
                       }
                   }

              }
           }
        }
      }

my directory structure

project dir/src/photos/markdown files
project dir/static/img/image files 

Is this something that could be more appropriately documented somewhere? Happy to submit a pr if so. I'm still not sure what the actual mechanism behind gatsby is that makes this possible. Is gatsby scanning all fields of all nodes and creating an imageSharpNode automatically if an image exists at a path?

All 6 comments

@maxcrane did you try the suggestions provided in this comment?

I thought I did, but I think I may have gotten the relative path incorrect the first time. I retried and it worked! Thank you for mentioning that specific comment! What I did was similar:

gatsby-node.js

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark` && node.frontmatter.image) {
      const path = `../../static${node.frontmatter.image}`;

       createNodeField({
          node,
          name: 'image',
          value: path
       });
}

graphql query

query PhotosPage {
        allMarkdownRemark(limit: 1000, filter: { fileAbsolutePath: {regex : "\/photos/"} }) {
           edges {
              node {
                 frontmatter {
                     tags
                     image
                   }
                   fields {
                        image {
                         childImageSharp {
                           fluid(maxWidth: 2000, quality: 100) {
                              ...GatsbyImageSharpFluid
                           }
                         }
                       }
                   }

              }
           }
        }
      }

my directory structure

project dir/src/photos/markdown files
project dir/static/img/image files 

Is this something that could be more appropriately documented somewhere? Happy to submit a pr if so. I'm still not sure what the actual mechanism behind gatsby is that makes this possible. Is gatsby scanning all fields of all nodes and creating an imageSharpNode automatically if an image exists at a path?

What you did is correct. Mine is also similar, but images are part of frontmatter instead of fields.

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  const { frontmatter } = node
  if (frontmatter) {
    const { image } = frontmatter
    if (image) {
      if (image.indexOf('/img') === 0) {
        frontmatter.image = path.relative(
          path.dirname(node.fileAbsolutePath),
          path.join(__dirname, '/static/', image)
        )
      }
    }
  }

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

And I call my images using:

import Img from 'gatsby-image'

<Img fluid={node.frontmatter.image.childImageSharp.fluid} />

(from the Docs: https://www.gatsbyjs.org/packages/gatsby-image/)

Old issues will be closed after 30 days of inactivity. This issue has been quiet for 20 days and is being marked as stale. Reply here or add the label "not stale" to keep this issue open!

This issue is being closed due to inactivity. Is this a mistake? Please re-open this issue or create a new issue.

gatsby-node.js

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark` && node.frontmatter.image) {
      const path = `../../static${node.frontmatter.image}`;

       createNodeField({
          node,
          name: 'image',
          value: path
       });
}

What if i have images on different places in frontmatter? For example node.frontmatter.product.image or node.frontmatter.image. Is there a way to deal with this automatically?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mikestopcontinues picture mikestopcontinues  路  3Comments

totsteps picture totsteps  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

dustinhorton picture dustinhorton  路  3Comments

3CordGuy picture 3CordGuy  路  3Comments