Using remote images with gatsby-image

928 Views Asked by At

I've got a series of promos on my Gatsby site that are pulling their data from a database using gatsby-source-mysql. Within this data, I have a node for images called ad_filename which, for example, returns ad_image_1.jpg. I've got the full asset URL set as an environmental variable, but since I'm only getting the filename in my graphql queries, I'm not able to use the plugin's built in remoteImageFieldNames and make the images work with gatsby-image. That being said, I'd like to so I can control dimensions/optimization etc. Is there a way to convert relative, remote paths to usable nodes?

This is my config for gatsby-source-mysql:

{
      resolve: `gatsby-source-mysql`,
      options: {
        connectionDetails: {
          host: process.env.GATSBY_DATABASE_HOST,
          user: process.env.GATSBY_DATABASE_USER,
          database: process.env.GATSBY_DATABASE_NAME,
          password: process.env.GATSBY_DATABASE_PASSWORD,
        },
        queries: [
          {
            statement: 'SELECT * FROM crm_dealers where state != ""',
            idFieldName: 'subdomain',
            name: 'Dealers',
          },
          {
            statement:
              'SELECT lm.*, d.subdomain domain FROM crm_lp_mgmt lm INNER JOIN crm_dealers d ON d.id = lm.dealer_id WHERE lm.ad_title != ""',
            idFieldName: 'id',
            name: 'Promos',
            parentName: 'Dealers',
            foreignKey: 'subdomain',
            cardinality: 'OneToMany',
          },
        ],
      },
    },

This is my query for the promos:

query Promos($subdomain: StringQueryOperatorInput = {}){
  allMysqlPromos(filter: { subdomain: $subdomain }) {
    edges {
      node {
        ad_filename
        ad_title
        ad_body
        URL_ext
        subdomain
      }
    }
  }
}

And this is what the query is returning:

{
  "data": {
    "allMysqlPromos": {
      "edges": [
        {
          "node": {
            "ad_filename": "ad_002910.jpg",
            "ad_title": "Buy One, Get One Free",
            "ad_body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam turpis quam venenatis porta sed. Aliquet eget lobortis quam ut dignissim eget quam lobortis. Elementum, at nullam tincidunt viverra pulvinar ac porta sed mauris. Sit leo imperdiet turpis morbi arcu, posuere odio sit.",
            "URL_ext": "/promo-jesse",
            "subdomain": "sacramento"
          }
        },
        {
          "node": {
            "ad_filename": "ad_002911.jpg",
            "ad_title": "Buy Two, Get Four Free",
            "ad_body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam turpis quam venenatis porta sed. Aliquet eget lobortis quam ut dignissim eget quam lobortis. Elementum, at nullam tincidunt viverra pulvinar ac porta sed mauris. Sit leo imperdiet turpis morbi arcu, posuere odio sit.",
            "URL_ext": "promo-jesse-two",
            "subdomain": "sacramento"
          }
        }
      ]
    }
  }
}

So, to clarify again, I make sure that the results of ad_filename are converted into nodes that I can run through childImageSharp for optimization etc. How can I do that?

Thanks in advance.

1

There are 1 best solutions below

2
On

Environment variables should store sensitive data, such as your host, user, database, or password, as you are doing. Store images URLs in that files is the main purpose of the file, moreover, having a MySQL database to store that information.

I would strongly suggest storing this kind of data in your database.

According to the documentation, you can use gatsby-image from a remote image using the URL as a parameter:

If your queries stores the remote url for image and you would like to utilize image processing of Gatsby, provide remoteImageFieldNames to the query object.

Make sure you’ve installed both gatsby-plugin-sharp and gatsby-transform-sharp packages and add them to your gatsby-config.js.

For example, assuming you have a actor table where the profile_url column stores the remote image url, e.g. 'https://cdn.pixabay.com/photo/2014/07/10/11/15/balloons-388973_1280.jpg'.

In your case:

{
      resolve: `gatsby-source-mysql`,
      options: {
        connectionDetails: {
          host: process.env.GATSBY_DATABASE_HOST,
          user: process.env.GATSBY_DATABASE_USER,
          database: process.env.GATSBY_DATABASE_NAME,
          password: process.env.GATSBY_DATABASE_PASSWORD,
        },
        queries: [
          {
            statement: 'SELECT * FROM crm_dealers where state != ""',
            idFieldName: 'subdomain',
            name: 'Dealers',
          },
          {
            statement:
              'SELECT lm.*, d.subdomain domain FROM crm_lp_mgmt lm INNER JOIN crm_dealers d ON d.id = lm.dealer_id WHERE lm.ad_title != ""',
            idFieldName: 'id',
            name: 'Promos',
            parentName: 'Dealers',
            foreignKey: 'subdomain',
            cardinality: 'OneToMany',
            remoteImageFieldNames: ['ad_filename']
          },
        ],
      },
    },  

Note: notice the remoteImageFieldNames: ['ad_filename'].

remoteImageFieldNames field is a column that contains an image URL that you want to download and utilize Gatsby's image processing capability.

That's it, Gatsby, using transformers and sharps will create a queryable node for that image where you will be able to add to your gatsby-image.

If you don't/not able to use the built-in method. You can still tell Gatsby that you have an image to be parsed locally by using Gatsby's filesystem:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/your/path/to/images/`,
  },
},

Note: of course, you can have multiple instances of gatsby-source-filesystem.

Gatsby will look into that directory and will parse what's inside (images in this case), creating the corresponding node for each image. You just need to query it with:

{
  allFile(filter: { sourceInstanceName: { eq: "images" } }) {
    edges {
      node {
        extension
        dir
        modifiedTime
      }
    }
  }
}

sourceInstanceName stands for the name in the gatsby-source-filesystem options. Add as many filters as needed to get your desired image.