Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load a local image on a gatsby source plugin?

Tags:

gatsby

I have a json file and a folder with images

plugins/
└── gatsby-source-cars/
    ├── images/
    ├── cars.json
    └── gatsby-node.js

the file cars.json contains an array and each index is an object that contains a key with the relative path to the image

I want to load the image file on sourceNodes instead just the path to use with gatsby-image plugin

like image 517
Mateus Sobral Avatar asked Dec 17 '22 17:12

Mateus Sobral


2 Answers

I assume that you want to process your local images with sharp since you said you want to use it with gatsby-image, this means you have gatsby-plugin-sharp and gatsby-transformer-sharp installed.

Usually gatsby-source-filesystem is necessary to load the image as File node. But gatsby-transformer-sharp only checks if a node has the field 'extension' and -- if it is one of the valid file types -- processes it. We can 'trick' it into thinking our node is a File node, by giving it the fields extension & absolutePath.

Given this structure:

plugins/
└── gatsby-source-my-plugin/
    ├── images/
    |     └──image01.png
    ├── images.json  //  [{ "01": "./images/image01.png" }]
    └── gatsby-node.js

gatsby-node.js could look like this:

const path = require('path')
const fs = require('fs-extra')

exports.sourceNodes = async ({ actions, createNodeId, createContentDigest }) => {
  const { createNode } = actions

  const imageList = await fs.readJson(path.resolve(__dirname, './images.json'))
  imageList.forEach(img => {

    const [ id, imgPath ] = Object.entries(img)[0]
    const { name, ext } = path.parse(imgPath) // get file name & extension
    const absolutePath = path.resolve(__dirname, imgPath)
    const data = {
      name,
      ext,
      absolutePath,                  // <-- required
      extension: ext.substring(1),   // <-- required, remove the dot in `ext`
    }
    const imageNode = {
      ...data,
      id: createNodeId(`my-plugin-image-${id}`),
      children: [],
      internal: {
        type: 'MyPluginNode',
        contentDigest: createContentDigest(data)
      }
    }

    createNode(imageNode)
  })
}

Later, you can query the images:

{
  allMyPluginNode {
    nodes {
      childImageSharp {
        fixed(width:200) {
          src
        }
      }
    }
  }
}
like image 194
Derek Nguyen Avatar answered Feb 01 '23 14:02

Derek Nguyen


A way to go about transforming image file paths in json to images with gatsby-image without tapping directly into gatsby-node.js is to use the plugin gatsby-transformer-json.

When used in conjunction with gatsby-source-filesystem, this allows you to query your json objects.

So assuming you have followed the setup for gatsby-image, if you have the following structure

src/
└── images/
    └──bar.png
└── content/
    └──foo.json

And foo.json contains relative links to the image locations such as

[
  {
    "name": "foo",
    "src": "../images/bar.png"
  }
]

Then you can query them like

query MyQuery {
  allFooJson {
    edges {
      node {
        name
        imgSrc {
          childImageSharp {
            fluid(maxHeight: 64, maxWidth: 64) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  }
}

Note that they must be relative links.

like image 37
Asher Lim Avatar answered Feb 01 '23 14:02

Asher Lim