How to Add a Background Image in Next.js?
- article

Introduction
This guide will show you how to add a background image to a HTML element in your Next.js app.
A background image is a decorative image placed behind other content within an HTML element. This is typically done using CSS's background-image
property.
background-image: url("/images/background.jpg");
Next.js Image Component
The Next.js Image component renders a single <img>
element, which means you cannot use it to apply a background image to a different element using CSS.
With the release of v14.1.0, Next.js added a new function called getImageProps( )
This function gives you access to some of the Next Image API and allows you to get props to pass to an HTML <img>
element. These props can then be used to apply inline CSS styles via the styles
prop:
const bgImage = getImageProps({
alt: "",
src: "https://picsum.photos/id/502/2560/800",
width: 2560,
height: 800,
// Has no effect, and does not add preload links to `<head>`.
priority: true,
});
return (
<div className="relative w-full h-[50vh] overflow-hidden">
<div
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
style={{
backgroundImage: `url(${bgImage.props.src})`,
}}
/>
</div>
);
However, preloading of background images is not supported, as setting priority
to true
has no effect, and does not add <link rel="preload" as="image">
tag to the document's <head>
.
Under the hood of the Next.js Image API, priority
prop only adds preload links to <head>
if it's used in combination with the <img>
element.
This is not ideal, and can create a performance problem if using a background image above the fold, and the image is flagged as the Largest Contentful Paint (LCP)
Next Image Plus
next-image-plus is a set of primitive React components, built on top of the Next.js Image API and React 19, which adds full support for picture and background images, including preloading for background images flagged as the Largest Contentful Paint (LCP).
Install the package
First we need to install next-image-plus package from npm:
npm install next-image-plus
Using the BackgroundImage component
To use the BackgroundImage
component, import it and set the id, className and images props:
import { BackgroundImage } from "next-image-plus";
<BackgroundImage
id="examples__background-image"
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
images={[
{
url: "https://picsum.photos/id/502/2560/800",
width: 2560,
height: 800,
},
]}
/>;
Under the hood the component will handle rendering the HTML markup, as well as applying the necessary CSS styles to set the background image.
Render the HTML markup with your id and class name:
<div id="examples__background-image" class="absolute inset-0 bg-cover bg-center bg-no-repeat"></div>
Add a <style>
tag to the document <head>
that generates the css for your background image:
<head>
<style data-href="examples__background-image" data-precedence="high">
#examples__background-image {
background-image: url(/_next/image?url=https://picsum.photos/id/502/2560/800&w=3840&q=75);
}
</style>
</head>
The <BackgroundImage />
component is not limited to just <div>
elements, but can be configured to render any HTML element, using the as
prop.
import { BackgroundImage } from "next-image-plus";
<BackgroundImage
id="examples__background-image"
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
images={[
{
url: "https://picsum.photos/id/502/2560/800",
width: 2560,
height: 800,
},
]}
as="span"
/>;
This will render the following HTML:
<span id="examples__background-image" class="absolute inset-0 bg-cover bg-center bg-no-repeat"></span>
Responsive Background Images
The <BackgroundImage />
component supports responsive background images. The images
prop accepts an array of image objects, and the media
prop can be used to set different background images for different screens:
import { BackgroundImage } from "next-image-plus";
<BackgroundImage
id="examples__responsive-background-image"
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
images={[
{
url: "https://picsum.photos/id/502/430/430",
media: "(max-width: 430px)",
width: 430,
height: 430,
},
{
url: "https://picsum.photos/id/502/768/768",
media: "(min-width: 430px) and (max-width: 768px)",
width: 768,
height: 768,
},
{
url: "https://picsum.photos/id/502/1024/1024",
media: "(min-width: 768px)",
width: 1024,
height: 1024,
},
]}
/>;
This will generate a <style>
tag and add it the document <head>
, including media queries:
<head>
<style
data-href="examples__responsive-background-image"
data-precedence="high"
>
#examples__responsive-background-image {
background-image: url(/_next/image?url=https://picsum.photos/id/502/430/430&w=860&q=75);
}
@media (min-width: 431px) and (max-width: 767px) {
#examples__responsive-background-image {
background-image: url(/_next/image?url=https://picsum.photos/id/502/768/768&w=1920&q=75);
}
}
@media (min-width: 768px) {
#examples__responsive-background-image {
background-image: url(/_next/image?url=https://picsum.photos/id/502/1024/1024&w=2048&q=75);
}
}
</style>
</head>
Preloading for LCP
If your <BackgroundImage />
component is above the fold, or flagged as the Largest Contentful Paint (LCP), it should be preloaded to improve performance.
Setting the preload
prop to true
will automatically handle this for you:
import { BackgroundImage } from "next-image-plus";
<BackgroundImage
id="examples__background-image-preload"
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
images={[
{
url: "https://picsum.photos/id/502/2560/800",
width: 2560,
height: 800,
},
]}
preload={true}
/>;
When preload
is set to true, the component will add a <link rel="preload" as="image">
tag to the document's <head>
<head>
<link
rel="preload"
as="image"
fetchpriority="high"
imagesrcset="/_next/image?url=https://picsum.photos/id/502/2560/800&w=3840&q=75 1x"
/>
</head>
This tells the browser that this image is a critical resource, which should be fetched as soon as possible. You can read more about preloading here
Conclusion
To see a more advanced example, you can check out the examples page
To learn more about the <BackgroundImage />
component, you can check out the API documentation
And if you find this package useful, please give us a star on GitHub