Search code examples
javascriptjsonimagegatsbysharp

Absolute Image Paths in Gatsby JSON


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?


Solution

  • 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
          }
        }
      }
    }