How to Load NextJS Images from an External URL
Jasser Mark Arioste
Hello, hustlers! In this tutorial, you'll learn how to load an image from an external URL in a NextJS project.
Introduction #
When loading images from an external URL, NextJS usually throws an error that a domain is not added in next.config.js. For example, if you're using the Image component in the following way:
import Image from "next/image" // ... <Image src="https://placehold.co/600x400" alt="sample image" width={600} height={400} /> //...
123456789
You'll probably get some error of the sort in development:
Unhandled Runtime Error Error: Invalid src prop (https://placehold.co/600x400) on `next/image`, hostname "placehold.co" is not configured under images in your `next.config.js` See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
12
When loading images from an external URL, there are basically three options. First is adding the domain in next.config.js
. Second, is using a custom image loader function in the Image component. Lastly, you can use the unoptimized
prop from the Image component.
Pre-requisites #
I assume you have basic knowledge of Nextjs.
The Recommended Way: Using images.domains
property
#
By default, NextJS recommends using the images.domains
property inside next.config.js
along with the Image
component to easily load an image from an external URL.
For example, if you want to load an image from placehold.co, you may add it to the config file:
//next /** @type {import('next').NextConfig} */ const nextConfig = { images: { domains: ["placehold.co"] } } module.exports = nextConfig
123456789
If you're deploying on Vercel, this will activate the caching and optimization mechanisms of NextJS, which retains the image URLs across each build to load the images faster for the average website visitor. This is an important thing to note because Vercel restricts the number of source URLs that you can cache. 1000 source URLs for the hobby plan, and 5000 source URLs for the pro plan.
You may not always want this feature. What if the images are already cached and optimized from the external URL? Using it this way is just redundant.
Using the unoptimized
prop in Image
#
The <Image/>
component provides the unoptimized
prop as another way to load images from an external URL. If the images are already optimized or there's no need for caching and optimization, you can use this property when rendering images. For example:
import Image from "next/image" // ... <Image src="https://placehold.co/600x400" alt="sample image" unoptimized width={600} height={400} /> //...
12345678910
Since it's unoptimized, you don't have to add the domain in the images.domains
property in next.config.js. This also won't increase your usage for Source URLs in Vercel.
Using the loader
prop in Image
#
Besides the unoptimized prop, the Image component provides another way to load images from an external URL through the loader
prop. The loader prop is a function that accepts an object which has the following properties: src
, width
, and quality
. Using the loader property is useful if you use another Image API that processes the image. For example.
import Image from "next/image" // ... <Image src="https://placehold.co/600x400" alt="sample image" loader={({ src, width, quality }) => { const url = new URL("https://myimageapi.co/optimize"); url.searchParams.append("src", src); url.searchParams.append("w", width + ""); url.searchParams.append("q", quality + ""); return url.toString(); }} width={600} height={400} /> // ...
12345678910111213141516
Since you are using a custom loader, you don't have to add the domain in the images.domains
property in next.config.js. This also won't increase your usage for Source URLs in Vercel.
Since it's a pain to add the loader prop every time you render an image, it's best to create a custom component for this. For example:
"use client"; import React from "react"; import Image, { ImageProps } from "next/image"; export type MyCustomImageProps = Omit<ImageProps, "loader">; const MyCustomImage = (props: MyCustomImageProps) => { return ( <Image {...props} alt={props.alt} loader={({ src, width, quality }) => { const url = new URL("https://myimageapi.co/optimize"); url.searchParams.append("src", src); url.searchParams.append("w", width + ""); url.searchParams.append("q", quality + ""); return url.toString(); }} /> ); }; export default MyCustomImage;
12345678910111213141516171819202122
That's basically it!
Conclusion #
You learned three different ways of loading images from an external URL in NextJS. At this point, you have to decide which method best fits your needs and project requirements.
If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on GitHub.
Resources #
Credits: Image by Nico Becker from Pixabay