Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions packages/gatsby-transformer-screenshot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,31 @@ Data should be in a YAML file named `sites.yml` and look like:

## Install

`npm install gatsby-transformer-screenshot`
```shell
npm install gatsby-transformer-screenshot
```

## How to use

```javascript
// in your gatsby-config.js
```js:title=gatsby-config.js
module.exports = {
plugins: [`gatsby-transformer-screenshot`],
plugins: [
{
resolve: `gatsby-transformer-screenshot`,
options: {
// See "Lambda setup" below to see how to create an endpoint
screenshotEndpoint: `your-aws-endpoint`,
}
}
],
}
```

By default, the plugin will target nodes sourced from a YAML file named `sites.yml`.

To source additional node types, supply an array of the types to a `nodeTypes` option on the plugin.

```javascript
// in your gatsby-config.js
```js:title=gatsby-config.js
module.exports = {
plugins: [
{
Expand Down Expand Up @@ -70,17 +78,17 @@ You can query for screenshot files as shown below:
}
```

screenshotFile is a PNG file like any other loaded from your filesystem, so you can use this plugin in combination with `gatsby-image`.
screenshotFile is a PNG file like any other loaded from your filesystem, so you can use this plugin in combination with `gatsby-plugin-image`.

## Lambda setup

Gatsby provides a hosted screenshot service for you to use; however, you can run the service yourself on AWS Lambda.
**You need to run a screenshot service on AWS Lamdba yourself.**

AWS Lambda is a "serverless" computing platform that lets you run code in response to events, without needing to set up a server. This plugin uses a Lambda function to take screenshots and store them in an AWS S3 bucket.

First, you will need to [create a S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html) for storing screenshots. Once you have done that, create a [Lifecycle Policy](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html) for the bucket that sets a number of days before files in the bucket expire. Screenshots will be cached until this date.
First, you will need to [create a S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html) for storing screenshots. Once you have done that, create a [Lifecycle Policy](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html) for the bucket that sets a number of days before files in the bucket expire. Screenshots will be cached until this date.

To build the Lambda package, run `npm run build-lambda-package` in this directory. A file called `lambda-package.zip` will be generated - upload this as the source of your AWS Lambda. Finally, you will need to set `S3_BUCKET` as an environment variable for the lambda.
To build the Lambda package, run `npm run build-lambda-package` in this directory. A file called `lambda-package.zip` will be generated - upload this as the source of your AWS Lambda. Finally, you will need to set `S3_BUCKET` as an environment variable for the lambda inside AWS.

To set up the HTTP interface, you will need to use AWS API Gateway. Create a new API, create a new resource under `/`, select "Configure as proxy resource", and leave all the settings with their defaults. Create a method on the new resource, selecting "Lambda Function Proxy" as the integration type, and fill in the details of your lambda.

Expand Down
28 changes: 11 additions & 17 deletions packages/gatsby-transformer-screenshot/src/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const axios = require(`axios`)
const Queue = require(`fastq`)
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)

const SCREENSHOT_ENDPOINT = `https://h7iqvn4842.execute-api.us-east-2.amazonaws.com/prod/screenshot`
const LAMBDA_CONCURRENCY_LIMIT = 50
const USE_PLACEHOLDER_IMAGE = process.env.GATSBY_SCREENSHOT_PLACEHOLDER

Expand All @@ -22,15 +21,13 @@ async function worker(input) {

exports.onPreBootstrap = (
{
store,
cache,
actions,
createNodeId,
getCache,
getNode,
getNodesByType,
createContentDigest,
reporter,
},
pluginOptions
) => {
Expand All @@ -55,14 +52,13 @@ exports.onPreBootstrap = (
screenshotQueue.push({
url: n.url,
parent: n.parent,
store,
cache,
createNode,
createNodeId,
getCache,
parentNodeId: n.id,
createContentDigest,
reporter,
pluginOptions,
})
} else {
// Screenshot hasn't yet expired, touch the image node
Expand Down Expand Up @@ -93,15 +89,10 @@ function shouldOnCreateNode({ node }, pluginOptions) {

exports.shouldOnCreateNode = shouldOnCreateNode

exports.onCreateNode = async ({
node,
actions,
store,
cache,
createNodeId,
createContentDigest,
getCache,
}) => {
exports.onCreateNode = async (
{ node, actions, store, cache, createNodeId, createContentDigest, getCache },
pluginOptions
) => {
const { createNode, createParentChildLink } = actions

try {
Expand All @@ -115,6 +106,7 @@ exports.onCreateNode = async ({
getCache,
createContentDigest,
parentNodeId: node.id,
pluginOptions,
})

createParentChildLink({
Expand All @@ -129,14 +121,13 @@ exports.onCreateNode = async ({
const createScreenshotNode = async ({
url,
parent,
store,
cache,
createNode,
createNodeId,
getCache,
parentNodeId,
createContentDigest,
reporter,
pluginOptions,
}) => {
try {
let fileNode
Expand All @@ -149,7 +140,10 @@ const createScreenshotNode = async ({
})
expires = new Date(2999, 1, 1).getTime()
} else {
const screenshotResponse = await axios.post(SCREENSHOT_ENDPOINT, { url })
const screenshotResponse = await axios.post(
pluginOptions.screenshotEndpoint,
{ url }
)

fileNode = await createRemoteFileNode({
url: screenshotResponse.data.url,
Expand Down