Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: preprocessing external images page #17497

Merged
merged 23 commits into from
Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
56437da
Initial work on preprocessing external images page
lannonbr Sep 9, 2019
1bf0b81
Applying Lennart's suggestions from code review
lannonbr Sep 15, 2019
f3ded70
Finishing up initial draft of post & adding images
lannonbr Sep 15, 2019
4fbdd71
Apply suggestions from Muescha code review
lannonbr Sep 16, 2019
5206d66
Removing 2nd "That said" in intro paragraphs
lannonbr Sep 16, 2019
6da663c
Apply suggestions from code review
lannonbr Sep 16, 2019
b3c750c
Update docs/docs/preprocessing-external-images.md
lannonbr Sep 16, 2019
ba53010
Update docs/docs/preprocessing-external-images.md
lannonbr Sep 16, 2019
970b797
Update preprocessing-external-images.md
lannonbr Sep 16, 2019
aa08e47
Updating with changes suggested by Muescha and Lennart
lannonbr Sep 16, 2019
0b43c9f
adding punctuation
lannonbr Sep 16, 2019
df9b0a3
Apply suggestions from code review
lannonbr Sep 16, 2019
3b94362
Update docs/docs/preprocessing-external-images.md
lannonbr Sep 16, 2019
7858b23
Apply suggestions from code review
lannonbr Sep 16, 2019
32cb4ac
Adding alt text for featured image through guide
lannonbr Sep 16, 2019
8fcb3b3
Update docs/docs/preprocessing-external-images.md
lannonbr Sep 17, 2019
918c7e2
Apply suggestions from code review
lannonbr Oct 6, 2019
352851f
Adding paragraph for mentioning Schema Customization API before code …
lannonbr Oct 6, 2019
0b41a5e
Add note that new node is not part of frontmatter
lannonbr Oct 6, 2019
c0d71ca
Apply suggestions from code review
lannonbr Oct 9, 2019
487091e
Merge remote-tracking branch 'origin/master' into docs/preprocessing-…
Oct 11, 2019
c54c76e
revert svg changes
wardpeet Oct 14, 2019
02a4e58
chore: remove svg changes
wardpeet Oct 14, 2019
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
Binary file added docs/docs/images/remote-file-node-blogpost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
151 changes: 151 additions & 0 deletions docs/docs/preprocessing-external-images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
title: Preprocessing External Images
---

Gatsby allows powerful image processing features through using the [`Sharp`](https://github.com/lovell/sharp/) library to automatically process images to be performant and have features like lazy-loading. That said, this only works if the image is a file node in the GraphQL layer.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

That said, if you want the same ecosystem for files that are hosted online and not located in your repo, [`gatsby-source-filesystem`](/packages/gatsby-source-filesystem/) has an API called `createRemoteFileNode` to solve this.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

This guide will walk you through how to use `createRemoteFileNode` process and get the same benefits of gatsby-transformer-sharp with externally sourced images.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

## Setup

A usecase that this technique can be useful is if you want to create a featured image in a blogpost, but the image is a url up on the web instead of a local file. This could be hosted somewhere like Imgur, S3, or anywhere up on the internet.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

Give a sample post,
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

```markdown
---
title: My first blogpost!
featuredImgUrl: https://images.unsplash.com/photo-1560237731-890b122a9b6c
---

Hello World
```

we can have a frontmatter field for the url of the featured image we want to pull down and use as part of the site.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

By default, this is just a string as we haven't told Gatsby how to interpret it, but now we can add some code into `gatsby-node.js` to modify it.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

## Gatsby Node

In your gatsby-node file, we can do some processing to create file nodes for the `featuredImgUrl` frontmatter field.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

```js:title=gatsby-node.js
const { createRemoteFileNode } = require("gatsby-source-filesystem")

exports.onCreateNode = async ({
node,
actions: { createNode },
store,
cache,
createNodeId,
}) => {
// For all MarkdownRemark nodes, call createRemoteFileNode
if (node.internal.type === "MarkdownRemark") {
lannonbr marked this conversation as resolved.
Show resolved Hide resolved
let fileNode = await createRemoteFileNode({
url: node.frontmatter.featuredImgUrl, // string that points to the URL of the image
parentNodeId: node.id, // id of the parent node of the fileNode we are going to create
lannonbr marked this conversation as resolved.
Show resolved Hide resolved
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.featuredImg___NODE = fileNode.id
}
}
}
```

Going step by step through the code:

1. Create an onCreateNode function so you can watch for when `MarkdownRemark` nodes are made.
2. use `createRemoteFileNode` by passing in the various required fields and get a reference to it afterwards.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved
3. if the node is created, attach it as a child of the original node. `___NODE` tells the graphql layer that the name before it is going to be a field on the parent node that links to another node. to do this, pass the id as the reference.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

And now since it is a file node, `gatsby-transformer-sharp` will pick it up and create a `childImageSharp` child node inside this newly created node.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

## Usage in templates

Now that the images are being generated and available in GraphQL, let's use it in action.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

If you open GraphiQL and write a query on the markdown nodes, you can see a new
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

```graphql
query {
allMarkdownRemark {
nodes {
featuredImg {
childImageSharp {
# ...
}
}
}
}
}
```

![Screenshot of GraphiQL with above query inserted](images/remote-file-node-graphiql-preview.png)

We can then use gatsby-transformer-sharp to fill in the query for a fluid image here.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

```graphql
query {
allMarkdownRemark {
nodes {
featuredImg {
childImageSharp {
fixed(width: 600) {
...GatsbyImageSharpFixed
}
}
}
}
}
}
```

And finally, we can update the template for this blogpost to include this image. This template is based on the one in [Part Seven](/tutorial/part-seven/) of the Gatsby Tutorial.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

```jsx
import React from "react"
import Img from "gatsby-image"
import { graphql } from "gatsby"

const template = ({ data }) => {
return (
<>
<h1>{data.markdownRemark.frontmatter.title}</h1>
<Img fixed={data.markdownRemark.featuredImg.childImageSharp.fixed} />
lannonbr marked this conversation as resolved.
Show resolved Hide resolved
<div dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }} />
</>
)
}

export default template

export const query = graphql`
query BlogPostQuery($slug: String) {
markdownRemark(fields: { slug: { eq: $slug } }) {
frontmatter {
title
}
html
featuredImg {
childImageSharp {
fixed(width: 600) {
...GatsbyImageSharpFixed
}
}
}
}
}
`
```

and if you run `gatsby develop`, you'll see the remote file locally now.
lannonbr marked this conversation as resolved.
Show resolved Hide resolved

![Screenshot of rendered blopost with featured image](images/remote-file-node-blogpost.png)
2 changes: 2 additions & 0 deletions www/src/data/sidebars/doc-links.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
- title: Working with Images in Markdown
link: /docs/working-with-images-in-markdown/
breadcrumbTitle: Images in Markdown
- title: Preprocessing External Images
link: /docs/preprocessing-external-images/
- title: Sourcing Content and Data
link: /docs/content-and-data/
items:
Expand Down