npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gatsby-source-s3-image

v1.6.221

Published

GatsbyJS plugin to source images from S3-compliant APIs, with EXIF-extracting superpowers.

Downloads

510

Readme

CircleCI npm Maintainability codecov

What is this?

gatsby-source-s3-image is a GatsbyJS Source plugin for converting images from any S3-compliant API[1] into GatsbyJS nodes.

[1] This includes AWS S3, of course, as well as third-party solutions like Digital Ocean Spaces, or open source / self-hosted products like MinIO.

But I can just query S3 manually client-side...

Sure, knock yourself out. But there are a few benefits you get out-of-the-box with this package:

  • Native integration with Gatsby's GraphQL data ontology, of course. You just provide the bucket details (and IAM credentials, if not public, which is recommended).
  • Several other benefits come with this tight integration with Gatsby API's, such as intelligent caching (nobody wants to wind up with an unexpected S3 bill as your CI server happily churns out builds, amiright?); automatic image asset optimization thanks to gatsby-image, etc.
  • And to top things off — gatsby-source-s3-image will automatically detect and extract image EXIF metadata from your photos, and expose this data at the GraphQL layer as node fields.

Tell me more about this EXIF stuff.

Currently supported EXIF fields that are automatically extracted when available include:

  • DateCreatedISO (string)
  • DateTimeOriginal (number)
  • ExposureTime (number)
  • FNumber (number)
  • FocalLength (number)
  • ISO (number)
  • LensModel (string)
  • Model (string)
  • ShutterSpeedValue (number)

These fields are properties of the "wrapper" node, S3ImageAsset. This type composes the ImageSharp node, the File node representing the cached image on disk (fetched via the RemoteFileNode API), and lastly the extracted EXIF data. As a result, you can easily retrieve both a set of images as well as any subset of their associated metadata in a single request — or just the metadata by itself, if that's all you need. For example:

export const pageQuery = graphql`
  query PhotographyPostsQuery {
    allS3ImageAsset {
      edges {
        node {
          id
          EXIF {
            DateCreatedISO
            ExposureTime
            FNumber
            ShutterSpeedValue
          }
          childrenFile {
            childImageSharp {
              original {
                height
                width
              }
              thumbnailSizes: fluid(maxWidth: 256) {
                aspectRatio
                src
                srcSet
                sizes
              }
              largeSizes: fluid(maxWidth: 1024) {
                aspectRatio
                src
                srcSet
                sizes
              }
            }
          }
        }
      }
    }
  }
`

Usage

Setup

Add the dependency to your package.json:

$ yarn add gatsby-source-s3-image
$ # Or:
$ npm install --save gatsby-source-s3-image

Next, register the plugin with the GatsbyJS runtime in the plugins field exported from your gatsby-config.js file, filling in the values to point to wherever your bucket is hosted:

const sourceS3 = {
  resolve: 'gatsby-source-s3-image',
  options: {
    bucketName: 'jesse.pics',
    domain: null, // [optional] Not necessary to define for AWS S3; defaults to `s3.amazonaws.com`
    protocol: 'https', // [optional] Default to `https`.
  },
}

const plugins = [
  sourceS3,
  // ...
]

module.exports = { plugins }

Querying

As mentioned above, gatsby-source-s3-image exposes nodes of type S3ImageAsset:

interface S3ImageAssetNode {
  id: string
  absolutePath: string
  ETag: string
  Key: string
  EXIF: ExifData | undefined // ExifData is defined below -->
  internal: {
    content: string
    contentDigest: string
    mediaType: string
    type: string
  }
}

interface ExifData {
  DateCreatedISO: string
  DateTimeOriginal: number
  ExposureTime: number
  FNumber: number
  FocalLength: number
  ISO: number
  LensModel: string
  Model: string
  ShutterSpeedValue: number
}

Not only can this be used to populate page data, I've found it useful in bootstrapping the pages themselves, e.g., to programmatically create dynamic Photo Gallery pages at build time depending on the contents of a bucket. For example:

// In `gatsby-node.js` -- using a query like this:
const photographyQuery = graphql`
  {
    allS3ImageAsset {
      edges {
        node {
          ETag
          EXIF {
            DateCreatedISO
          }
        }
      }
    }
  }
`

// We can then dynamically generate pages based on EXIF data, like this:
const createPages = ({ actions }) => {
  const { createPage } = actions
  const photographyTemplate = path.resolve(
    './src/templates/photography-post.js'
  )

  const createPhotographyPosts = edges => {
    // Create the photography "album" pages -- these are a collection of photos
    // grouped by ISO date.
    const imagesGroupedByDate = _.groupBy(edges, 'node.EXIF.DateCreatedISO')
    _.each(imagesGroupedByDate, (images, date) => {
      createPage({
        path: `/photography/${date}`,
        component: photographyTemplate,
        context: {
          name: date,
          datetime: DateTime.fromISO(date),
          type: PageType.Photography,
        },
      })
    })
  }
}

Nota Bene: Gatsby Version Compatibility

gatsby-source-s3-image was recently updated to support Gatsby V2, which required some breaking changes. The Gatsby V1-compatible version of the plugin is still fully functional, and will continue to receive maintenance updates as necessary. The last release compatible with Gatsby V1 can be found here.