Last updated: June 11, 2025

How to Add a Background Image in Next.js?

  • article
William Luisi

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");

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 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).

First we need to install next-image-plus package from npm:

npm install next-image-plus

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>

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>

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

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