05 September 2023
An example of using the `placeholder` prop of the Next.js <Image> component
Contentful account. If you don't have an account yet - sign up here. It's free!
Next.JS v13 app. For our example, I just started a new app using create-next-app
. If you haven't set up one yet, you can follow its official installation guide.
First, let's do a short introduction about the Next.js <Image>
Component. It's an extension of the <img />
element that provides various features for optimization and developer experience. This component comes with massive advantages over the <img />
element. Some of its benefits are:
It automatically resizes your images based on its container
It lazy loads images meaning they will be only loaded once they enter the viewport
It can prevent Cumulative Layout Shift (CLS) by utilizing placeholder
The component has 4 required props - src
, alt
, height
, and width
.
The height
and width
can be optional if the image is statically imported or the fill
prop is set to true.
In this article, we will not be going through all of the <Image />
properties and benefits. Instead, we will focus on how to use its placeholder
prop and why it is important.
The placeholder
prop is an optional prop in the <Image />
component. Its use for displaying a temporary image while the actual image is loading. Common placeholders include spinners, skeletons, and the blurred version of the actual image. You can use the placeholder
prop to do all of these types of placeholders, but in this case, we will only do the blurred version.
Below are the possible values for the placeholder prop in the <Image>
Component.
Value | Description |
---|---|
empty | The default value. No placeholder will be used. Just a blank space while the image is loading. |
blur | How this works depends on the value of the If the If the |
data:image/... | Displays the provided Data URL value. This is useful if you want to display a custom placeholder. |
Now let's create the example for each prop value.
This is the basic use of <Image /> component with fill=true
.
As you can see below, there's just a blank space while the image loads.
Image `placeholder` prop with it's default value - empty
With this value, the blurred placeholder is automatically generated.
By simply adding placeholder="blur"
, you can have the blurred version of the image. Isn't that amazing?
Next.js Image `blur` Placeholder example
If the src
value is from a remote source, we need to define the value of blurDataURL
. For the placeholder, I blurred our example image from Unsplash in Photoshop first. If you don't have Photoshop, you can use Photopea or other editors that can generate a blurred version of our image to be used as a placeholder. Then, I searched online for an image-to-Base64 converter to get the Base64 format.
In addition to this, we have to configure our next.config.js and add images.unsplash.com to the list of hostnames that are allowed to serve images.
next.config.js
Next.js <Image /> with remote source and placeholder = `blur`
The process of creating the placeholder for this value is the same as in the previous example. I just blurred it in a different way. This prop value can give you more flexibility in what you want to display as your image loads. However, it is important to keep in mind that placeholders should be performant.
Next.j <Image /> with the provided Data URL placeholder
All these examples use static image data. How about if we want the blurred placeholder to be dynamically generated based on the dynamic src
value?
For dynamic images, we will use Contentful as our remote source. Let's install the following packages first:
sharp - is a server-side library for optimizing images and a dependency for plaiceholder
to work
plaiceholder - is a plugin that allows you to create low-quality image placeholder (LQIP) in the server using sharp
@plaiceholder/next - is a plugin for Next.js that makes it easier to use plaiceholder
Let's rename our next.config.js
to next.config.mjs
. Then, same with images.unsplash.com, we also need to add images.ctfassets.net in the domains
. Finally, wrap our nextConfig
with withPlaiceholder
from @plaiceholder/next
.
next.config.mjs
Now let's create our asset in Contentful. Upload a new asset to your Contentful account. To upload, in your Contentful dashboard, click Media -> Add asset -> Single asset. Fill out the fields and upload our example image from Unsplash. After uploading, publish the entry and get the entry id. We will use this to get the entry on our Next.js app.
To get the entry id, click on the Info. You should see the Entry Id below the Content Type details or get it from the URL:
https://app.contentful.com/spaces/{space_id}/assets/{entry_id}
We will then re-use how we set up our Next.js app Contentful from my previous blog.
/app/(image)/dynamic/page.jsx
We are almost done. Let's create the component that will display our new Contentful Asset.
/components/ImageDynamicPlaceholderBlur/index.jsx
We will now create an API route that we will use getPlaiceholder
from plaiceholder
to generate the Base64.
Actually, getPlaiceholder
returns other strategies for LQIP, such as Color
, SVG
, and CSS
. You can explore these other strategies if Base64
does not suit your use case.
/app/api/plaiceholder/route.js
Next.j <Image /> with Contentful data
That's it! You can check the demo site or view the source code. Don't forget to disable or clear your browser cache, and/or throttle your network to see the placeholder. I used a large image size so that the placeholder would be visible.
Learn more