Procesar imágenes externas con Gatsby desde una API.

January 8, 2020 • ☕️ 2 minutos de lectura

Procesar imágenes externa con Gatsby (desde una api API)

Gatsby nos permite procesar las imágenes usando Sharp, una biblioteca que nos optimiza el rendimiento de nuestras imágenes, entre sus peculiaridades tiene la carga diferida.

Para esto Gatsby nos ofrece gatsby-source-filesystem una API llamada createRemoteFileNode.

En este artículo veremos como obtener todos los beneficios de gatsby-transformer-sharp desde imágenes externas.

Para ello primero debemos convertir nuestra api a graphql usando el plugin gatsby-source-apiserver, lo explico en el siguiente enlace Peticiones a una API Rest con Gatsby

Supongamos que nuestra api nos devuelve un array de objetos similar a este:

[
  {
    titulo:
      "Post numero 1",
    id: "1974",
    images: [
      {
        alt: "descripción de tu imagen",
        url:
          "https://ruta-de-la-imagen/5c18a859d8cab9f41be6fd8b28eca75d.jpg"
      },
      {
        alt: "descripción de tu imagen",
        url:
          "https://ruta-de-la-imagen/0c86636d7d6343d65cfe7ffad0730a16.jpg"
      },
      {
        alt: "descripción de tu imagen",
        url:
          "https://ruta-de-la-imagen/8c1ccd5d5d09bf3d9a3f9f57cb6e8fcf.jpg"
      },
      {
        alt: "descripción de tu imagen",
        url:
          "https://ruta-de-la-imagen/53641081c9792534af2a0d58ad8da17e.jpg"
      },
      {
        alt: "descripción de tu imagen",
        url:
          "https://ruta-de-la-imagen/62046bbd88451eb1842c549c7b810315.jpg"
      }
    ]
  },
  // ... más posts con similar estructura
]

Una vez tengamos todo listo, debemos editar el dichero gatsby-node.js y usar onCreateNode, este es llamado cada vez que se crea un nodo y contiene toda la información de dicho nodo.

gatsby-node.js

exports.onCreateNode = async ({
  node,
  actions: { createNode, createNodeField },
  store,
  cache,
  createNodeId,
}) => {
  if (node.internal.type === "apiInmuebles") {
    if (node.images && !isEmpty(node.images)) {
      var images = await Promise.all(
        node.images.map(async image => {
          let fileNode

          try {
            fileNode = await createRemoteFileNode({
              url: image.url,
              parentNodeId: node.id, // id of the parent node of the fileNode you are going to create
              createNode, // helper function in gatsby-node to generate the node
              createNodeId, // helper function in gatsby-node to generate the node id
              cache, // Gatsby's cache
              store, // Gatsby's redux store
            })
          } catch (e) {
            console.log("e", e)
          }
          if (fileNode) {
            console.log("createdFile node")
            image.localFile___NODE = fileNode.id
            return image
          }
        })
      )

      await createNodeField({
        node,
        name: "images",
        value: images,
      })
    }
  }
}