How to Use gatsby-remark-images
Thank you for your continued support.
This article contains advertisements that help fund our operations.
Table Of Contents
This article summarizes how to use gatsby-remark-images
, a plugin for Gatsby.js.
Brief Plugin Overview
Plugins with remark
in their names are often tools that format and build Markdown articles. The main feature of gatsby-remark-images
is to enhance and output image files written within Markdown articles.
Features
Processes images in markdown so they can be used in the production build.
In the processing, it makes images responsive by:
Adding an elastic container to hold the size of the image while it loads to avoid layout jumps.
Generating multiple versions of images at different widths and sets the srcset and sizes of the img element so regardless of the width of the device, the correct image is downloaded.
Using the “blur up” technique popularized by Medium and Facebook where a small 20px wide version of the image is shown as a placeholder until the actual image is downloaded.
Practical Experience with the Plugin
- Builds images and makes them responsive.
- Prevents layout shifts during page load (CLS: Cumulative Layout Shift).
- Adjusts image sizes based on the device.
- Displays a near-0-byte blurred image before the actual image fully loads.
- Reduces image weight with WebP.
- Enables lazy loading.
These features were quite helpful.
How to Install
Install the required plugins via command
npm install gatsby-remark-images gatsby-plugin-sharp gatsby-transformer-remark
Add to gatsby.config.js
Be careful not to duplicate plugins when adding gatsby-remark-images
.
plugins: [
`gatsby-plugin-sharp`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 620,
},
},
],
},
},
]
Place images where the filesystem is defined or define a new location
gatsby.config.js
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content-images`,
path: `${__dirname}/src/images`,
},
},
Call images from the Markdown file with relative paths
The path may vary depending on your environment.
![](../../images/sample.png)
For more details on specifying paths, check this article:
Gatsby.js: How to Easily Convert Article Images to WebP for Lightweight Performance
Checking the Detailed Behavior After Setup
Output Results
<a
class="gatsby-resp-image-link"
href="/static/70b8b9146729bb8ea24a7cbd117c0fd7/21b4d/mailtrap.png"
target="\_blank"
rel="noopener"
style="display: block;"
>
<span
class="gatsby-resp-image-background-image"
style='padding-bottom: 56.3291%; position: relative; bottom: 0px; left: 0px; background-image: url("data:image/png;base64,..."); background-size: cover; display: block; opacity: 0;'
>
</span>
>
<picture>
<source
srcset="/static/70b8b9146729bb8ea24a7cbd117c0fd7/81b7c/mailtrap.webp 158w /static/70b8b9146729bb8ea24a7cbd117c0fd7/6ea66/mailtrap.webp 315w /static/70b8b9146729bb8ea24a7cbd117c0fd7/8aab1/mailtrap.webp 630w /static/70b8b9146729bb8ea24a7cbd117c0fd7/a70f5/mailtrap.webp 945w /static/70b8b9146729bb8ea24a7cbd117c0fd7/4ef06/mailtrap.webp 1260w /static/70b8b9146729bb8ea24a7cbd117c0fd7/af3f0/mailtrap.webp 1280w"
sizes="(max-width: 630px) 100vw, 630px"
type="image/webp"
/>
<source
srcset="/static/70b8b9146729bb8ea24a7cbd117c0fd7/c26ae/mailtrap.png 158w /static/70b8b9146729bb8ea24a7cbd117c0fd7/6bdcf/mailtrap.png 315w /static/70b8b9146729bb8ea24a7cbd117c0fd7/f058b/mailtrap.png 630w /static/70b8b9146729bb8ea24a7cbd117c0fd7/40601/mailtrap.png 945w /static/70b8b9146729bb8ea24a7cbd117c0fd7/78612/mailtrap.png 1260w /static/70b8b9146729bb8ea24a7cbd117c0fd7/21b4d/mailtrap.png 1280w"
sizes="(max-width: 630px) 100vw, 630px"
type="image/png"
/>
<img
class="gatsby-resp-image-image"
src="/static/70b8b9146729bb8ea24a7cbd117c0fd7/f058b/mailtrap.png"
alt="mailtrap"
title=""
loading="lazy"
decoding="async"
style="width: 100%; height: 100%; margin: 0px; vertical-align: middle; position: absolute; top: 0px; left: 0px; opacity: 1; color: inherit; box-shadow: white 0px 0px 0px 400px inset;"
/>
</picture>
</a>
Optimized Image Sizes Based on Devices
The output defines files corresponding to 158w, 315w, 630w, 945w, 1260w, and 1280w. This prevents large, unnecessary files from being fetched depending on the device width.
By the way, 630
is likely the max-width specified, and 1280
is the original image width.
Preventing Layout Shifts During Image Load (CLS)
The span
tag above the picture
tag provides padding-bottom based on the aspect ratio, which fills the space before the actual image loads, preventing layout shifts. For example:
Image width = 630px
Image height = 355px
Aspect ratio
= (height / width) * 100
= (355 / 630) * 100
= 56.3291%
The percentage varies based on the image, and the plugin calculates and applies this in HTML. Amazing!
Blurred Placeholder Before the Image Fully Loads
The span
tag also includes a background-image, which is a base64-compressed blurred image. This acts as a placeholder background until the full image is loaded.
Lightweight Images with WebP
By configuring the options in gatsby-config.js
, the plugin compresses images into WebP format, reducing file sizes without sacrificing quality.
For more details on setting options, see below.
Lazy Loading
The img
tag contains:
loading="lazy"
This enables lazy loading. Additionally,
decoding="async"
These are the default settings, but you can change them through options.
Option Settings
You can modify the settings by adding properties to the options
object.
plugins: [
`gatsby-plugin-sharp`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 620,
},
},
],
},
},
]
You can mostly understand it by reading the documentation, but I’ll summarize it below.
Specifying Maximum Width
You can specify the maximum width for an image, and if there’s leftover space, it will be centered.
options: {
maxWidth: 620
}
Linking Images or Not
This option toggles whether clicking on images in the post will open the original image (before compression) in a new window. By default, it is enabled.
This might be useful for images that need to be viewed in more detail.
options: {
linkImagesToOriginal: false
}
Adding ALT Text Below the Image
As in the image above, you can add text below the image. The text seems to come from the ALT tag.
options: {
showCaptions: true
}
Displaying Text Below the Image in Markdown
As in the image above, it displays the text in Markdown.
If showCaptions
is false, this will not be displayed.
options: {
showCaptions: true,
markdownCaptions: true,
},
![## あああ](../../images/sample.png)
Applying Styles to the Image Wrapper Tag
You can add styles to the span
tag that wraps around the picture
tag.
It seems like you can do a lot with this. For example, the background color changes on hover.
options: {
wrapperStyle: "margin-bottom:10px; background: red;",
}
Changing Background Color
This adds a background color to the img
tag.
Essentially, this sets the color to display when the image fails to load, such as due to a 404 error.
In most cases, setting it to the same color as the article’s background should prevent any odd display.
- Setting it to
transparent
makes the image’s background transparent. - Setting it to
none
completely removes the image’s background.
options: {
backgroundColor: "transparent",
},
Resolution During Compression
I think this option is used when you want to lower the resolution for especially heavy images.
Before using this, I recommend trying to compress the image using Avif or webp.
options: {
quality: 50
},
Outputting as WebP
This compresses the original image into webp format and does a great job.
WebP provides better compression than jpg, making it more lightweight.
It also supports transparency, so it works well with round images.
I think it would be extremely difficult to do this manually, so I’m really grateful for this feature.
options: {
withWebp: true
//withWebp: { quality: 80 },
},
Outputting as Avif
This compresses the original image into Avif format and does a great job.
Avif offers even better compression than webp, making the images even lighter.
This would be incredibly difficult to do manually, so I’m doubly grateful for this.
It’s so amazing that I almost want to turn into Zundamon out of joy.
options: {
withAvif: true,
// withAvif: { quality: 80 },
},
Changing the Blurry Placeholder Image
You can change the blurred image during loading with the tracedSVG
option.
Honestly, I didn’t quite understand how to do this, so all I could do was smile awkwardly.
The blurred image looks stylish, so I’ve decided to stick with it.
[Translation] Instead of the "blur up" effect, use a traced SVG for the placeholder image. If you want to use the traced SVG with the default settings, set it to true. If you want to override the default, pass an object. For example, passing { color: "#F00", turnPolicy: "TURNPOLICY_MAJORITY" } changes the trace color to red and sets the turn policy to TURNPOLICY_MAJORITY. For a full list of available options and descriptions, refer to the node-potrace parameter documentation.
https://www.gatsbyjs.com/plugins/gatsby-remark-images/#options
(In my test environment, I couldn’t figure out what this changed.)
tracedSVG: { color: "#F00", turnPolicy: "TURNPOLICY_MAJORITY" }
Changing the loading
Attribute
You can change the loading="lazy"
attribute on the img
tag.
This controls lazy loading behavior.
options: {
loading: 'lazy'// eager,auto
},
Loading Asynchronously or Not
You can change the decoding="async"
attribute on the img
tag.
This allows images to be loaded asynchronously, without affecting the loading of other elements.
options: {
decoding: 'async'// sync or auto
},
Disabling Blur-Up for Images with Transparent Pixels
You can disable the blur-up effect for images with transparent pixels, as such images may display unnaturally.
[Translation] Images with transparent pixels at the edges will have blurred edges. As a result, these images do not work well with the "blur-up" technique used by this plugin.
options: {
disableBgImageOnAlpha: true,
}
Removing Background Images and Styles
[Translation] Removes the background image and its inline styles.
This is useful for preventing the "Stylesheet too long" error in AMP.
AMP is a technique for displaying web content quickly.
There doesn’t seem to be a need to enable this unless you have a specific reason.
options: {
disableBgImage: true
},
Changing Responsive Breakpoints for Images
From the output earlier, we saw that the following breakpoints were set:
158w, 315w, 630w, 945w, 1260w, 1280w
options: {
srcSetBreakpoints: [200, 340, 520, 890],
},
I tried this setting.
As a result:
<source
srcset="/static/70b8b9146729bb8ea24a7cbd117c0fd7/772e8/mailtrap.png 200w /static/70b8b9146729bb8ea24a7cbd117c0fd7/9f933/mailtrap.png 340w /static/70b8b9146729bb8ea24a7cbd117c0fd7/69902/mailtrap.png 520w /static/70b8b9146729bb8ea24a7cbd117c0fd7/f058b/mailtrap.png 630w /static/70b8b9146729bb8ea24a7cbd117c0fd7/4ef49/mailtrap.png 890w /static/70b8b9146729bb8ea24a7cbd117c0fd7/21b4d/mailtrap.png 1280w"
sizes="(max-width: 630px) 100vw, 630px"
type="image/png"
/>
Now, the breakpoints are 200w, 340w, 520w, 630w, 890w, 1280w
.
The 630 and 1280 are the same as before, but the others reflect the new values I set.
My Favorite Options
I’m really fond of withWebp
and withAvif
.
For example, an image of 180kb can be reduced to about 300b after compression.
That’s about 1/600th the size, and the appearance on the page doesn’t change much. Clicking on the image still shows the original, so it doesn’t hurt the user experience.
Thanks.
Downsides
I think the only downside is the increase in build time.
However, I’m still within the free tier on Netlify. Even with about 200 articles and 150 images, the total build time is around 5 minutes.
Honestly, I didn’t notice much of an increase in build time, so I don’t think it has much impact with this amount of images.
Also, I believe images that have been built once are cached, so adding this plugin shouldn’t significantly increase costs.
Conclusion
I’ve summarized the behavior and my impressions of using the gatsby-remark-images
plugin.
I apologize for the points I couldn’t fully explain.
I hope this helps someone.