Working with media information in Gatsby may not be as simple as anticipated. I keep in mind beginning my first Gatsby mission. After consulting Gatsby’s documentation, I found I wanted to make use of the gatsby-source-filesystem plugin to make queries for native information. Simple sufficient!
That’s the place issues began getting difficult. Want to make use of photographs? Verify the docs and set up one — or extra! — of the numerous, many plugins out there for dealing with photographs. How about working with SVG information? There may be one other plugin for that. Video information? You get the concept.
It’s all nice till any of these plugins or packages change into outdated and go unmaintained. That’s the place the complications begin.
In case you are unfamiliar with Gatsby, it’s a React-based static web site generator that makes use of GraphQL to tug structured information from numerous sources and makes use of webpack to bundle a mission so it will possibly then be deployed and served as static information. It’s basically a static web site generator with reactivity that may pull information from an unlimited array of sources.
Like many static web site frameworks within the Jamstack, Gatsby has historically loved an important status as a performant framework, though it has taken successful in recent times. Based mostly on what I’ve seen, nonetheless, it’s not a lot that the framework is quick or gradual however how the framework is configured to deal with most of the types of issues that influence efficiency, together with media information.
So, let’s clear up the complications you may encounter when working with media information in a Gatsby mission. This text is the primary of a short two-part collection the place we’ll look particularly on the media you’re almost definitely to make use of: photographs, video, and audio. After that, the second a part of this collection will get into several types of information, together with Markdown, PDFs, and even 3D fashions.
Fixing Picture Complications In Gatsby
I feel that the method of optimizing photographs can fall into 4 totally different buckets:
Optimize picture information.
Minimizing a picture’s file dimension with out dropping high quality instantly results in shorter fetching occasions. This may be performed manually or throughout a construct course of. It’s additionally potential to make use of a service, like Cloudinary, to deal with the work on demand.
Prioritize photographs which might be a part of the First Contentful Paint (FCP).
FCP is a metric that measures the time between the purpose when a web page begins loading to when the primary bytes of content material are rendered. The concept is that fetching property which might be a part of that preliminary render earlier leads to sooner loading somewhat than ready for different property decrease on the chain.
Lazy loading different photographs.
We are able to stop the remainder of the photographs from render-blocking different property utilizing the loading=”lazy” attribute on photographs.
Load the suitable picture file for the suitable context.
With responsive photographs, we will serve one model of a picture file at one display screen dimension and serve one other picture at a distinct display screen dimension with the srcset and sizes attributes or with the <image> aspect.
These are nice rules for any web site, not solely these constructed with Gatsby. However how we construct them right into a Gatsby-powered web site will be complicated, which is why I’m writing this text and maybe why you’re studying it.
Lazy Loading Pictures In Gatsby
We are able to apply a picture to a React part in a Gatsby web site like this:
import * as React from “react”;
import forest from “./property/photographs/forest.jpg”;
const ImageHTML = () => {
return <img src={ forest } alt=”Forest path” />;
};
It’s essential to import the picture as a JavaScript module. This lets webpack know to bundle the picture and generate a path to its location within the public folder.
This works superb, however when are we ever working with just one picture? What if we wish to make a picture gallery that comprises 100 photographs? If we attempt to load that many <img> tags directly, they are going to actually gradual issues down and will have an effect on the FCP. That’s the place the third precept that makes use of the loading=”lazy” attribute can come into play.
import * as React from “react”;
import forest from “./property/photographs/forest.jpg”;
const LazyImageHTML = () => {
return <img src={ forest } loading=”lazy” alt=”Forest path” />;
};
We are able to do the alternative with loading=”keen”. It instructs the browser to load the picture as quickly as potential, no matter whether or not it’s onscreen or not.
import * as React from “react”;
import forest from “./property/photographs/forest.jpg”;
const EagerImageHTML = () => {
return <img src={ forest } loading=”keen” alt=”Forest path” />;
};
Implementing Responsive Pictures In Gatsby
It is a fundamental instance of the HTML for responsive photographs:
srcset=”./property/photographs/forest-400.jpg 400w, ./property/photographs/forest-800.jpg 800w”
sizes=”(max-width: 500px) 400px, 800px”
alt=”Forest path”
/>
In Gatsby, we should import the photographs first and go them to the srcset attribute as template literals so webpack can bundle them:
import * as React from “react”;
import forest800 from “./property/photographs/forest-800.jpg”;
import forest400 from “./property/photographs/forest-400.jpg”;
const ResponsiveImageHTML = () => {
return (
<img
srcSet={`
${ forest400 } 400w,
${ forest800 } 800w
`}
sizes=”(max-width: 500px) 400px, 800px”
alt=”Forest path”
/>
);
};
That ought to maintain any responsive picture complications sooner or later.
Loading Background Pictures In Gatsby
What about pulling within the URL for a picture file to make use of on the CSS background-url property? That appears one thing like this:
import * as React from “react”;
import “./model.css”;
const ImageBackground = () => {
return <div className=”banner”></div>;
};
/* model.css */
.banner {
aspect-ratio: 16/9;
background-size: cowl;
background-image: url(“./property/photographs/forest-800.jpg”);
/* and many others. */
}
That is simple, however there’s nonetheless room for optimization! For instance, we will do the CSS model of responsive photographs, which hundreds the model we wish at particular breakpoints.
/* model.css */
@media (max-width: 500px) {
.banner {
background-image: url(“./property/photographs/forest-400.jpg”);
}
}
Utilizing The gatsby-source-filesystem Plugin
Earlier than going any additional, I feel it’s price putting in the gatsby-source-filesystem plugin. It’s a necessary a part of any Gatsby mission as a result of it permits us to question information from numerous directories within the native filesystem, making it easier to fetch property, like a folder of optimized photographs.
npm i gatsby-source-filesystem
We are able to add it to our gatsby-config.js file and specify the listing from which we’ll question our media property:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `assets`,
path: `${ __dirname }/src/assets`,
},
},
],
};
Keep in mind to restart your improvement server to see adjustments from the gatsby-config.js file.
Now that we’ve gatsby-source-filesystem put in, we will proceed fixing just a few different image-related complications. For instance, the subsequent plugin we have a look at is able to simplifying the cures we used for lazy loading and responsive photographs.
Utilizing The gatsby-plugin-image Plugin
The gatsby-plugin-image plugin (to not be confused with the outdated gatsby-image plugin) makes use of strategies that routinely deal with numerous features of picture optimization, similar to lazy loading, responsive sizing, and even producing optimized picture codecs for contemporary browsers.
As soon as put in, we will change customary <img> tags with both the <GatsbyImage> or <StaticImage> elements, relying on the use case. These elements benefit from the plugin’s options and use the <image> HTML aspect to make sure probably the most applicable picture is served to every person based mostly on their gadget and community situations.
We are able to begin by putting in gatsby-plugin-image and the opposite plugins it is dependent upon:
Let’s add them to the gatsby-config.js file:
// gatsby-config.js
module.exports = {
plugins: [
// other plugins
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`],
};
This supplies us with some options we’ll put to make use of a bit later.
Utilizing The StaticImage Part
The StaticImage part serves photographs that don’t require dynamic sourcing or complicated transformations. It’s notably helpful for situations the place you’ve gotten a hard and fast picture supply that doesn’t change based mostly on person interactions or content material updates, like logos, icons, or different static photographs that stay constant.
The principle attributes we’ll take into accounts are:
src: This attribute is required and must be set to the trail of the picture you wish to show.
alt: Supplies various textual content for the picture.
placeholder: This attribute will be set to both blurred or dominantColor to outline the kind of placeholder to show whereas the picture is loading.
format: This defines how the picture must be displayed. It may be set to mounted for, as you may think, photographs with a hard and fast dimension, fullWidth for photographs that span your entire container, and constrained for photographs scaled down to suit their container.
loading: This determines when the picture ought to begin loading whereas additionally supporting the keen and lazy choices.
Utilizing StaticImage is much like utilizing a daily HTML <img> tag. Nonetheless, StaticImage requires passing the string on to the src attribute so it may be bundled by webpack.
import * as React from “react”;
import { StaticImage } from “gatsby-plugin-image”;
const ImageStaticGatsby = () => {
return (
<StaticImage
src=”./property/photographs/forest.jpg”
placeholder=”blurred”
format=”constrained”
alt=”Forest path”
loading=”lazy”
/>
);
};
The StaticImage part is nice, however it’s important to take its constraints into consideration:
No Dynamically Loading URLs
One of the vital limitations is that the StaticImage part doesn’t help dynamically loading photographs based mostly on URLs fetched from information sources or APIs.
Compile-Time Picture Dealing with
The StaticImage part’s picture dealing with happens at compile time. Which means the photographs you specify are processed and optimized when the Gatsby web site is constructed. Consequently, you probably have photographs that want to alter ceaselessly based mostly on person interactions or updates, the static nature of this part may not suit your wants.
Restricted Transformation Choices
In contrast to the extra versatile GatsbyImage part, the StaticImage part supplies fewer transformation choices, e.g., there isn’t any solution to apply complicated transformations like cropping, resizing, or adjusting picture high quality instantly inside the part. It’s possible you’ll wish to think about various options in the event you require superior transformations.
Utilizing The GatsbyImage Part
The GatsbyImage part is a extra versatile resolution that addresses the restrictions of the StaticImage part. It’s notably helpful for situations involving dynamic picture loading, complicated transformations, and superior customization.
Some superb use circumstances the place GatsbyImage is especially helpful embrace:
Dynamic Picture Loading
If you should load photographs dynamically based mostly on information from APIs, content material administration methods, or different sources, the GatsbyImage part is the go-to selection. It might fetch photographs and optimize their loading habits.
Advanced transformations
The GatsbyImage part is well-suited for superior transformations, utilizing GraphQL queries to use them.
Responsive photographs
For responsive design, the GatsbyImage part excels by routinely producing a number of sizes and codecs of a picture, making certain that customers obtain an applicable picture based mostly on their gadget and community situations.
In contrast to the StaticImage part, which makes use of a src attribute, GatsbyImage has a picture attribute that takes a gatsbyImageData object. gatsbyImageData comprises the picture info and will be queried from GraphQL utilizing the next question.
question {
file(identify: { eq: “forest” }) {
childImageSharp {
gatsbyImageData(width: 800, placeholder: BLURRED, format: CONSTRAINED)
}
identify
}
}
When you’re following alongside, you’ll be able to go searching your Gatsby information layer at http://localhost:8000/___graphql.
From right here, we will use the useStaticQuery hook and the graphql tag to fetch information from the information layer:
import * as React from “react”;
import { useStaticQuery, graphql } from “gatsby”;
import { GatsbyImage, getImage } from “gatsby-plugin-image”;
const ImageGatsby = () => {
// Question information right here:
const information = useStaticQue(graphql“);
return <div></div>;
};
Subsequent, we will write the GraphQL question inside the graphql tag:
import { useStaticQuery, graphql } from “gatsby”;
const ImageGatsby = () => {
const information = useStaticQuery(graphqlquery {
file(identify: { eq: “forest” }) {
childImageSharp {
gatsbyImageData(width: 800, placeholder: BLURRED, format: CONSTRAINED)
}
identify
}
});
return <div></div>;
};
Subsequent, we import the GatsbyImage part from gatsby-plugin-image and assign the picture’s gatsbyImageData property to the picture attribute:
import { useStaticQuery, graphql } from “gatsby”;
import { GatsbyImage } from “gatsby-plugin-image”;
const ImageGatsby = () => {
const information = useStaticQuery(graphqlquery {
file(identify: { eq: “forest” }) {
childImageSharp {
gatsbyImageData(width: 800, placeholder: BLURRED, format: CONSTRAINED)
}
identify
}
});
return <GatsbyImage picture={ information.file.childImageSharp.gatsbyImageData } alt={ information.file.identify } />;
};
Now, we will use the getImage helper perform to make the code simpler to learn. When given a File object, the perform returns the file.childImageSharp.gatsbyImageData property, which will be handed on to the GatsbyImage part.
import { useStaticQuery, graphql } from “gatsby”;
import { GatsbyImage, getImage } from “gatsby-plugin-image”;
const ImageGatsby = () => {
const information = useStaticQuery(graphqlquery {
file(identify: { eq: “forest” }) {
childImageSharp {
gatsbyImageData(width: 800, placeholder: BLURRED, format: CONSTRAINED)
}
identify
}
});
const picture = getImage(information.file);
return <GatsbyImage picture={ picture } alt={ information.file.identify } />;
};
Utilizing The gatsby-background-image Plugin
One other plugin we may use to benefit from Gatsby’s picture optimization capabilities is the gatsby-background-image plugin. Nonetheless, I don’t suggest utilizing this plugin since it’s outdated and vulnerable to compatibility points. As a substitute, Gatsby suggests utilizing gatsby-plugin-image when working with the newest Gatsby model 3 and above.
If this compatibility doesn’t characterize a major drawback in your mission, you’ll be able to consult with the plugin’s documentation for particular directions and use it instead of the CSS background-url utilization I described earlier.
Fixing Video And Audio Complications In Gatsby
Working with movies and audio is usually a little bit of a large number in Gatsby because it lacks plugins for sourcing and optimizing these kind of information. In actual fact, Gatsby’s documentation doesn’t identify or suggest any official plugins we will flip to.
Which means we must use vanilla strategies for movies and audio in Gatsby.
Utilizing The HTML video Component
The HTML video aspect is able to serving totally different variations of the identical video utilizing the <supply> tag, very similar to the img aspect makes use of the srset attribute to do the identical for responsive photographs.
That enables us to not solely serve a extra performant video format but in addition to offer a fallback video for older browsers that will not help the bleeding edge:
import * as React from “react”;
import natureMP4 from “./property/movies/nature.mp4”;
import natureWEBM from “./property/movies/nature.webm”;
const VideoHTML = () => {
return (
<video controls>
<supply src={ natureMP4 } kind=”video/mp4″ />
<supply src={ natureWEBM } kind=”video/webm” />
</video>
);
};
P;
We are able to additionally apply lazy loading to movies like we do for photographs. Whereas movies don’t help the loading=”lazy” attribute, there’s a preload attribute that’s related in nature. When set to none, the attribute instructs the browser to load a video and its metadata solely when the person interacts with it. In different phrases, it’s lazy-loaded till the person faucets or clicks the video.
We are able to additionally set the attribute to metadata if we wish the video’s particulars, similar to its period and file dimension, fetched straight away.
<video controls preload=”none”>
<supply src={ natureMP4 } kind=”video/mp4″ />
<supply src={ natureWEBM } kind=”video/webm” />
</video>
Observe: I personally don’t suggest utilizing the autoplay attribute since it’s disruptive and disregards the preload attribute, inflicting the video to load straight away.
And, like photographs, show a placeholder picture for a video whereas it’s loading with the poster attribute pointing to a picture file.
<video controls preload=”none” poster={ forest }>
<supply src={ natureMP4 } kind=”video/mp4″ />
<supply src={ natureWEBM } kind=”video/webm” />
</video>
Utilizing The HTML audio Component
The audio and video components behave equally, so including an audio aspect in Gatsby seems to be practically equivalent, apart from the aspect:
import * as React from “react”;
import audioSampleMP3 from “./property/audio/pattern.mp3”;
import audioSampleWAV from “./property/audio/pattern.wav”;
const AudioHTML = () => {
return (
<audio controls>
<supply src={ audioSampleMP3 } kind=”audio/mp3″ />
<supply src={ audioSampleWAV } kind=”audio/wav” />
</audio>
);
};
As you may count on, the audio aspect additionally helps the preload attribute:
<audio controls preload=”none”>
<supply src={ audioSampleMP3 } kind=”audio/mp3″ />
<supply src={a udioSampleWAV } kind=”audio/wav” />
</audio>
That is most likely pretty much as good as we will do to make use of movies and pictures in Gatsby with efficiency in thoughts, apart from saving and compressing the information as greatest we will earlier than serving them.
Fixing iFrame Complications In Gatsby
Talking of video, what about ones embedded in an <iframe> like we’d do with a video from YouTube, Vimeo, or another third occasion? These can actually result in efficiency complications, but it surely’s not as we’ve direct management over the video file and the place it’s served.
Not all is misplaced as a result of the HTML iframe aspect helps lazy loading the identical method that photographs do.
const VideoIframe = () => {
return (
<iframe
src=”https://www.youtube.com/embed/jNQXAC9IVRw”
title=”Me on the Zoo”
permit=”accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture”
allowFullScreen
loading=”lazy”
/>
);
};
Embedding a third-party video participant through iframe can presumably be a neater path than utilizing the HTML video aspect. iframe components are cross-platform suitable and will scale back internet hosting calls for in case you are working with heavy video information by yourself server.
That mentioned, an iframe is basically a sandbox serving a web page from an out of doors supply. They’re not weightless, and we’ve no management over the code they include. There are additionally GDPR issues in relation to companies (similar to YouTube) as a result of cookies, information privateness, and third-party adverts.
Fixing SVG Complications In Gatsby
SVGs contribute to improved web page efficiency in a number of methods. Their vector nature leads to a a lot smaller file dimension in comparison with raster photographs, and so they will be scaled up with out compromising high quality. And SVGs will be compressed with GZIP, additional lowering file sizes.
That mentioned, there are a number of ways in which we will use SVG information. Let’s sort out each within the contact of Gatsby.
Utilizing Inline SVG
SVGs are basically traces of code that describe shapes and paths, making them light-weight and extremely customizable. Resulting from their XML-based construction, SVG photographs will be instantly embedded inside the HTML <svg> tag.
import * as React from “react”;
const SVGInline = () => {
return (
<svg viewBox=”0 0 24 24″ fill=”#000000″>
<!– and many others. –>
</svg>
);
};
Simply keep in mind to alter sure SVG attributes, similar to xmlns:xlink or xlink:href, to JSX attribute spelling, like xmlnsXlink and xlinkHref, respectively.
Utilizing SVG In img Parts
An SVG file will be handed into an img aspect’s src attribute like some other picture file.
import * as React from “react”;
import image from “./property/svg/image.svg”;
const SVGinImg = () => {
return <img src={ image } alt=”Image” />;
};
Loading SVGs inline or as HTML photographs are the de facto approaches, however there are React and Gatsby plugins able to simplifying the method, so let’s have a look at these subsequent.
Inlining SVG With The react-svg Plugin
react-svg supplies an environment friendly solution to render SVG photographs as React elements by swapping a ReactSVG part within the DOM with an inline SVG.
As soon as putting in the plugin, import the ReactSVG part and assign the SVG file to the part’s src attribute:
import * as React from “react”;
import { ReactSVG } from “react-svg”;
import digicam from “./property/svg/digicam.svg”;
const SVGReact = () => {
return <ReactSVG src={ digicam } />;
};
Utilizing The gatsby-plugin-react-svg Plugin
The gatsby-plugin-react-svg plugin provides svg-react-loader to your Gatsby mission’s webpack configuration. The plugin provides a loader to help utilizing SVG information as React elements whereas bundling them as inline SVG.
As soon as the plugin is put in, add it to the gatsby-config.js file. From there, add a webpack rule contained in the plugin configuration to solely load SVG information ending with a sure filename, making it simple to separate inline SVGs from different property:
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: “gatsby-plugin-react-svg”,
options: {
rule: {
include: /.inline.svg$/,
},
},
},
],
};
Now we will import SVG information like some other React part:
import * as React from “react”;
import Guide from “./property/svg/ebook.inline.svg”;
const GatsbyPluginReactSVG = () => {
return <Guide />;
};
And similar to that, we will use SVGs in our Gatsby pages in a number of other ways!
Conclusion
Although I personally love Gatsby, working with media information has given me various complications.
As a remaining tip, when needing widespread options similar to photographs or querying out of your native filesystem, go forward and set up the mandatory plugins. However whenever you want a minor function, strive doing it your self with the strategies which might be already out there to you!
If in case you have skilled totally different complications when working with media in Gatsby or have circumvented them with totally different approaches than what I’ve coated, please share them! It is a large house, and it’s all the time useful to see how others strategy related challenges.
Once more, this text is the primary of a short two-part collection on curing complications when working with media information in a Gatsby mission. The next article can be about avoiding complications when working with totally different media information, together with Markdown, PDFs, and 3D fashions.
Additional Studying
“Demystifying The New Gatsby Framework”
“Gatsby Complications And How To Treatment Them: i18n (Half 1)”
“Gatsby Complications And How To Treatment Them: i18n (Half 2)”
Subscribe to MarketingSolution.
Receive web development discounts & web design tutorials.
Now! Lets GROW Together!