Your plugin should support both Gatsby Image CDN and downloading images as local file nodes

We added back support for downloading the YouTube thumbnails as local file nodes on yesterday's apparently deceiful and spam-packed treasure hunt in the sharky waters around the Gatsby islands

Hi Queen Raae, Our team has reviewed your content, and we think you may need to make changes to make sure it doesn't violate our spam, deceptive practices and scams policy. In the meantime, we've made the following content private

We removed it in exchanging for ImageCDN on a treasure hunt with Ward of Gatsby, but as we are working on a plugin, I later realized it should support both 🤦‍♀️

Screengrab of Ward stream

The What?

Let the user of our plugin (gatsby-source-youtube-oembed) decide if they want to utilize Gatsby ImageCDN or download remote images as local file nodes.

The Why?

We don't know where our users are deploying their sites as plugin authors. As far as I know, only Netlify and Gatsby Cloud support Gatsby ImageCDN at the moment, and it's pretty clear they'll charge extra for it in the future. Also, some Gatsby users deploy to their own servers or other static hosts.

The How

We added a plugin option letting the user configure their choice:

// gatsby-node.js
exports.pluginOptionsSchema = ({ Joi }) => {
  return Joi.object({
    thumbnailMode: Joi.string().valid("none", "cdn", "download").default("cdn"),
  });
};

Then we made sure to check the plugin option in onCreateNode to decide what type of thumbnail node to make:

// gatsby-node.js
const { createRemoteFileNode } = require("gatsby-source-filesystem");

exports.onCreateNode = async (gatsbyUtils, pluginOptions) => {
  const { node, actions, createNodeId, getCache } = gatsbyUtils;
  const { createNode, createNodeField } = gatsbyUtils.actions;

  if (node.internal.type === YOUTUBE_TYPE) {
    if (pluginOptions.thumbnailMode === "cdn") {
      createNode({
        id: createNodeId(`Thumbnail >>> ${node.youTubeId}`),
        parent: node.id,
        youTubeId: node.youTubeId,
        url: node.oEmbed.thumbnail_url,
        mimeType: "image/jpeg",
        filename: node.youTubeId + ".jpg",
        height: node.oEmbed.thumbnail_height,
        width: node.oEmbed.thumbnail_width,
        internal: {
          type: "YouTubeThumbnail",
          contentDigest: node.internal.contentDigest,
        },
      });
    } else if (pluginOptions.thumbnailMode === "download") {
      const imageFile = await createRemoteFileNode({
        url: node.oEmbed.thumbnail_url,
        parentNodeId: node.id,
        getCache,
        createNode,
        createNodeId,
      });

      createNodeField({
        node: node,
        name: "thumbnailFileId",
        value: imageFile.id,
      });
    }
  }
};

and we recheck it to customize the schema according to the chosen mode:

// gatsby-node.js
const {
  addRemoteFilePolyfillInterface,
} = require("gatsby-plugin-utils/polyfill-remote-file");

exports.createSchemaCustomization = (gatsbyUtils, pluginOptions) => {
  const { actions, schema } = gatsbyUtils;

  if (pluginOptions.thumbnailMode === "cdn") {
    const YouTubeType = `
      type YouTube implements Node {
        thumbnail: YouTubeThumbnail @link(from: "youTubeId" by: "youTubeId")
      }
    `;

    const YouTubeThumbnailType = addRemoteFilePolyfillInterface(
      schema.buildObjectType({
        name: `YouTubeThumbnail`,
        fields: {
          youTubeId: "String!",
        },
        interfaces: [`Node`, `RemoteFile`],
      }),
      {
        schema,
        actions,
      }
    );

    actions.createTypes([YouTubeType, YouTubeThumbnailType]);
  } else if (pluginOptions.thumbnailMode === "download") {
    const YouTubeType = `
      type YouTube implements Node {
        thumbnail: File @link(from: "fields.thumbnailFileId" by: "id")
      }
    `;
    actions.createTypes(YouTubeType);
  }
};

We should also update our docs, of course, with examples of how to get hold of the thumbnail image data in both modes, but that is for a later work session.

To see a full diff check out the Pull Request on Github.

 
All the best,
Queen Raae

Interested in more daily treasures like this one?
Sent directly to your inbox?