How Images Work in Gatsby


Where possible, we always recommend storing your images in Agility CMS's Assets area. These are automatically deployed to a CDN and support basic image transcoding via query-strings. You can simply continue to use the CDN URLs provided for your content without any additional work.

However, one of the primary benefits of having a static website is that nothing on your site can change without a new build. This ensures your website updates are atomic. If you are using CDN links to images though, in your site, one could alter an image and that change would take effect immediately on your site. You'd also have no way of reliably rolling back your site to a previous version since the images on the CDN are managed separately.

Using Gatsby Image

Gatsby was designed to be used with local images which are then transcoded automatically during the build and provide you the most optimized versions of your images and they seamlessly integrate with some great frontend packages that further optimize how images are used in your site.

You can use the Gatsby Image component with Agility CMS Assets, or any other remote image you may have. In order to do this, you'll need to download the images and store them locally in order for them to be queryable in GraphQL and ready for use with the `gatsby-image` component.

You can do this by adding some code in your gatsby-node.js that looks for attachment fields on content and automatically downloads each image. 

exports.onCreateNode = async ({
    actions: { createNode },
  }) => {
    // For all Agility nodes that have an attachment field, call createRemoteFileNode
    if (
      node.internal.type.indexOf(`agility`)  > -1 && 
      && (
          node.internal.type.indexOf(`agilitypage`) == -1 &&
          node.internal.type.indexOf(`agilitystate`) == -1 &&
          node.internal.type.indexOf(`agilitysitemap`) == -1 &&
          node.internal.type.indexOf(`agilitynestedsitemap`) == -1 &&
          node.internal.type.indexOf(`agilitySitemapNode`) == -1 &&
          node.internal.type.indexOf(`agilityitem`) == -1
    ) {
        const customFields = Object.keys(node.customFields);
        await asyncForEach(customFields, async (field) => {
            const fieldKeys = Object.keys(node.customFields[field]);
                fieldKeys.includes(`url`) &&
                fieldKeys.includes(`pixelHeight`) &&
                fieldKeys.includes(`pixelWidth`) &&
                fieldKeys.includes(`width`) &&
            ) {
                console.log(`found ${field} on ${node.internal.type}`)
                let fileNode = await createRemoteFileNode({
                    url: node.customFields[field].url, // string that points to the URL of the image
                    parentNodeId:, // 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
                  // if the file was created, attach the new node to the parent node
                  if (fileNode) {
                    node.customFields[`${field}LocalImg___NODE`] =

What it does:

  1. Checks every Agility CMS content node being created to see if it is using an attachment field
  2. If it is, it downloads and saves the image via createRemoteFileNode 
  3. If the name of the attachment field found was `picture`, then it creates a new field for the local image called `pictureLocalImg` which is queryable via GraphQL `childImageSharp`. See this example of it being used on posts on our starter site


2 out of 2 found this helpful



Please sign in to leave a comment.