3

I am using gatsby-transformer-json to query JSON files in Gatsby. There are image URLs within the JSON file, however they are absolute file paths and Gatsby only transforms relative paths into image nodes.

My JSON:

{
  "defaultImage": "images/defaultImage.jpg"
}

My query:

metadataJson {
  defaultImage {
    childImagageSharp {
      fixed(width: 3200, height: 2133) {
        ...GatsbyImageSharpFixed
      }
    }
  }
}

However this fails with an error because Gatsby is encountering the absolute path and because it isn't relative, it doesn't transform it to a Sharp image node.

If it was a Markdown file I could transform the path myself and save it to the Markdown node's fields object. However that option isn't available to me with gatsby-transformer-json.

How can I transform the absolute path in a JSON file so that Gatsby will replace the path with a Sharp image node?

Undistraction
  • 42,754
  • 56
  • 195
  • 331

1 Answers1

2

You can use createNodeField on any type of nodes, not just markdown remark.

If you set up gatsby-config.js like the following:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: `${__dirname}/content/meta`, <-- folder name is used to create node type name, i.e `MetaJson`
    name: `meta`, <-- doesn't affect json node's type name
  },
},
`gatsby-transformer-json`,

You can then transform them in gatsby-node.js just like how you would do it with MarkdownRemark node.

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

  if (node.internal.type === `MetaJson`) {
    const relativePath = ...

    createNodeField({
      node,
      name: `foo`,
      value: relativePath,
    })
  }
}

You can also pass in additional options into gatsby-transformer-json to have more fine grain control of the json nodes' internal type name.


And just like with markdown transformed by gatsby-transformer-remark, jsons transformed by gatsby-transformer-json also attach a child node onto its parent File node:

{
  file( sourceInstanceName: { eq: "meta" } ) {
    dir
    childMetaJson {
      fields {
        foo
      }
    }
  }
}
Derek Nguyen
  • 11,294
  • 1
  • 40
  • 64
  • Thank you. This approach looks correct, but no matter what I do, I cannot get Gatsby to transform the path into a File node, even if I use the path of another frontmatter image that is correctly transformed. It just ignores the value and leaves it as a string. – Undistraction Feb 13 '19 at 16:41
  • @Undistraction It's hard to tell without more context, but I think the problem could be that if gatsby found a node whose field didn't link to a file, it'll assume the type of that field for all other nodes (of the same node type). Is your project happened to be open source? Or could you replicate the problem in a small repo? – Derek Nguyen Feb 14 '19 at 03:10