62

I use the Next.js Image component for image optimization. It works great on dev but it doesn't load images from external URLs in production.

What can I do?

2
  • I dropped nextjs Image compoenent, using img, its simple even though not optimized. Commented Aug 27, 2023 at 8:58
  • This feature has never worked for me!!!!! even though tried all possible solutions!!!! Commented Sep 21, 2024 at 18:28

12 Answers 12

133

You need to set the configuration in the next.config.js file first.

For Example:

on next.config.js

module.exports = {
    images: {
        domains: ['images.unsplash.com'],
    },
}

on pages/your_page_file.tsx

<Image
    alt="The guitarist in the concert."
    src="https://images.unsplash.com/photo-1464375117522-1311d6a5b81f?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=2250&q=80"
    width={2250}
    height={1390}
    layout="responsive"
/>

For versions above 12.3.0 this is the accepted approach:

module.exports = {
    images: {
        remotePatterns: [
            {
                protocol: 'https',
                hostname: 'assets.example.com',
                port: '',
                pathname: '/account123/**',
            },
        ],
    },
}

Refer https://nextjs.org/docs/messages/next-image-unconfigured-host

Sign up to request clarification or add additional context in comments.

5 Comments

This should be the accepted answer.
just make sure to restart your terminal for the change to take effect!
Newer version of NextJS allow a more specific conf using remotePatterns. See nextjs.org/docs/messages/next-image-unconfigured-host (domains key is still a working solution)
What if users wanna show many url from internet? Add 1000 domains?>?
@NicholasJela Maybe the edited version by CromulentCoder is what you are looking for.
20

If you want to display any images in nextjs app from accross the internet; here is my next config:

const nextConfig = {
    reactStrictMode: true,
    i18n,
    sassOptions: {
        includePaths: [path.join(__dirname, 'src/styles')],
        prependData: `@import "variables.scss";`,
    },
    images: {
        remotePatterns: [
            {
                protocol: 'https',
                hostname: '**',
                port: '',
                pathname: '**',
            },
        ],
    },
}

I am giving an update for this answer because I change my usage. My new code example like this:

const path = require('path');

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: true,
    sassOptions: {
        includePaths: [path.join(__dirname, 'src/styles')],
        prependData: `@import "variables.scss";`,
    },
    images: {
        remotePatterns: [
            {
                protocol: 'https',
                hostname: 'example.com',
                port: '',
                pathname: '**',
            },
            {
                protocol: 'https',
                hostname: 'another-example.com',
                port: '',
                pathname: '**',
            },
        ],
    },
}

export default nextConfig;

I change it because of security. If you know the domain you want to fetch images from, it is better to specify them explicitly rather than using wildcard patterns.

This helps to mitigate potential security risks by limiting the sources from which images can be loaded. It also improves performance by reducing unnecessary network requests to unknown domains.

2 Comments

You should mention this config.js is not work on production....
how did it worked for me ?
7

Add and declare your domain in your next config, next.config.js:

module.exports = {
    reactStrictMode: true,
    images: {
        domains: ["yourDomain.com"],
        formats: ["image/webp"],
    },
};

The configuration file, next.config.js, should be in the root of your project.

And lastly, restart project even in dev mode.

Comments

6

For future references, I was having the same problem after deploying my next.js site to Netlify. Only later, reading my logs, I found

Image domains set in next.config.js are ignored. Please set the env variable NEXT_IMAGE_ALLOWED_DOMAINS to "cdn.sanity.io" instead

So this is probably something to note. In the meanwhile before I saw it, I plugged this next-sanity-image plugin https://www.sanity.io/plugins/next-sanity-image to my page, which also bypassed the problem

5 Comments

Actually, It finally worked on the local build but still having the same issue on docker built on the server!
Hum, I didn't use Docker so I don't know if there's an extra config for this case. You used the env variable on netlify or the plugin?
I have a home server for nextjs where I deployed it with docker container. All env. variables (public/private) are working fine but I can't make this image trusted domain work. I even tried this docker container on my local machine and I got the same error over there too. Despite docker, they work fine when I execute my project with yarn start
@op_exchanger You have to add the variable on netlify itself. Here are the steps to do so - docs.netlify.com/configure-builds/environment-variables/…
@FarrokhRostamiKia Did you try ensuring you're copying the next.config.js to the Docker envionment? Spotted this issue with some useful suggestions in that thread
2

I noticed you're having trouble with next/image not loading external images after deployment. I faced a similar issue, and after some tweaking, here's the configuration that worked for me:

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**',
        port: '',
        pathname: '**',
      },
    ],
  },
}

module.exports = nextConfig

Feel free to give this configuration a try, and let me know if it resolves your problem. If you have any other questions or run into further issues, I'm here to help!

Comments

2

I had the same problem, although I had configured remotePatterns in next.config.js correctly.

Finally, I realized that in my Dockerfile the next.config.js was not copied to the final stage when building the image. As a result, no remote source was allowed during execution and accordingly no image was loaded.

I was able to solve the problem by adding the COPY line for the next.config.js file to the final stage:

COPY --from=builder /app/next.config.js ./

Comments

0

echoing @adamduncan , Next.JS will error out in local development if the domain is not set in next.config.* - More likely is that in the deployed environment, you forgot to copy the config file over in the Dockerfile execution.

Comments

0

Keep in mind that using environment variables can break this.

I was using Next.js with Docker (using the official Next.js Dockerfile) and AWS Elastic Beanstalk wasn't passing environment variables to the Dockerfile during build. I had a similar next.config.js:

const s3Bucket = process.env.S3_BUCKET;
const nextConfig = {
  output: 'standalone',
  images: s3Bucket ? { remotePatterns: [{ hostname: s3Bucket }] } : undefined,
};

However, with output: 'standalone', the remotePatterns config option is inlined in the resulting server.js file of the docker image. If you open that file, you would see something like this:

const nextConfig = {/* JSON containing `remotePatterns` */}

process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)

In my case, since the S3_BUCKET variable was not available, the remotePatterns option was not ending up in the final docker image. So I just had to hardcode the domain in my next.config.js.

Comments

0

I tried many ways to fix it, but nothing worked. Then, I created a next.config.js file in my server's root folder and added my development code inside it. After that, it worked.

Here is the code:

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  trailingSlash: false,
  eslint: {
    ignoreDuringBuilds: true,
  },
  experimental: {
    scrollRestoration: true,
  },
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "yourdomain.com",
      },
    ],
  },
  
};

module.exports = nextConfig;

Comments

0

I tried the remote pattern method because i was using drive links to preview images and using /uc for google drive wasn't a stable solution at all specially for production so instead of adding additional configuration to my next.config.js/mjs I used another function for proxy images which solved my problem.

Here's the function I used ;


export default async function handler(req, res) {
  const { id } = req.query;

  if (!id) {
    return res.status(400).json({ error: "Missing Google Drive file ID" });
  }

  const imageUrl = `https://drive.google.com/uc?export=view&id=${id}`;

  try {
    const response = await fetch(imageUrl);

    if (!response.ok) {
      return res.status(500).json({ error: "Failed to fetch image from Google Drive" });
    }

    const contentType = response.headers.get("content-type");
    res.setHeader("Content-Type", contentType);

    const buffer = await response.arrayBuffer();
    res.send(Buffer.from(buffer));
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Server error" });
  }
}

to use it put this function in you next js /src/pages/api/image-proxy.js

and then use it in your components like

'use client';
import Image from "next/image";
 
export default function Search() {
  return(
    <>
   <div className="m2">search</div>
   <Image src="/api/image-proxy?id=1Yi7hyEGrDj59F7dumyrJCJNt0ib89kmc"

    width={2250}
    height={1390}
    layout="responsive"
/>
  </>);
}

Comments

0

For those still experiencing this issue, you can load your image from an external link as shown below:

<Image
    src={item.ImageUrl}
    alt={`Imagefor ${item.title}`}
    width={300}
    height={450}
    className="h-full w-full object-cover"
    data-ai-hint="external image"
    unoptimized   //<-----  just add this option
    onError={(e) => {
      // Fallback to a placeholder if the image fails to load
      e.currentTarget.srcset = 'https://placehold.co/500x750/333333/ffffff?text=Error';
    }}
  />

Comments

-5

For me, it was just an Ad-Blocker extension.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.