How to Configure Automatic Downloading of Remote Images in next-export-optimize-images

To configure automatic downloading of remote images, define the remoteImages option in your export-images.config.js file as either a static array or an async function returning URLs, and optionally set remoteImagesDownloadsDelay to control request throttling.

The dc7290/next-export-optimize-images library treats external image URLs as local build-time assets, downloading them during the export process to enable optimization, caching, and offline serving. By configuring remoteImages, you ensure that specified external images are fetched once at build time, written to your static output directory, and referenced through optimized <RemoteImage> components without runtime network latency.

Understanding the remoteImages Configuration Schema

The configuration interface for remote images is defined in src/utils/getConfig.ts at lines 104‑110. The library expects your export-images.config.js to export an object containing the remoteImages key, which accepts either an array of URL strings or a function that resolves to an array.

// export-images.config.js
module.exports = {
  remoteImages: [
    'https://example.com/assets/logo.png',
    'https://cdn.example.org/photos/hero.jpg',
  ],
};

When the build process initializes, the plugin loads this configuration in src/withExportImages.ts (lines 31‑41) and prepares the list for manifest generation.

Static vs. Dynamic Remote Image Lists

You can supply remote image URLs as a static array for fixed assets, or as an asynchronous function for dynamic generation from APIs, databases, or environment variables.

Static Array Configuration

Use a static array when your remote image URLs are known at development time and do not change between builds. This is the simplest approach for logos, static banners, or fixed CDN assets.

module.exports = {
  remoteImages: [
    'https://example.com/logo.png',
    'https://assets.site.com/hero.jpg',
  ],
  remoteImagesDownloadsDelay: 200, // Optional: 200ms between requests
};

Dynamic Function Configuration

For dynamically generated URLs, export an async function that returns (or resolves to) an array of strings. The library automatically executes this function during the build phase, as implemented in src/withExportImages.ts lines 37‑41.

module.exports = {
  remoteImages: async () => {
    const response = await fetch('https://my-api.com/images');
    const data = await response.json();
    return data.map((img) => `https://assets.my-cdn.com/${img.path}`);
  },
  remoteImagesDownloadsDelay: 500,
};

This pattern is essential when your image inventory is stored in a headless CMS or external asset management system.

Build-Time Download Process

When you execute next build and next export, the library orchestrates the remote image handling through three distinct phases:

  1. Manifest Generation: In src/cli/index.ts (lines 84‑101), the CLI iterates over your remoteImages list and creates manifest entries for every responsive image size that Next.js would generate.
  2. HTTP Downloading: The externalImagesDownloader function in src/cli/external-images/index.ts (lines 30‑44) performs the actual fetch operations, respecting the remoteImagesDownloadsDelay interval between requests to avoid rate-limiting.
  3. File System Writing: Downloaded binaries are written to the directory specified by externalImageDir (default _next/static/media), as referenced in src/cli/index.ts lines 13‑15.

The same download logic is reused when server components render in production. The RemoteImage component in src/components/server/remote-image.tsx (lines 24‑30) registers remote URLs during server-side rendering, ensuring they are cached and optimized identically to local assets.

Advanced Configuration Options

Beyond the basic URL list, you can fine-tune the download behavior and storage location.

Throttling Downloads with remoteImagesDownloadsDelay

Set remoteImagesDownloadsDelay to a millisecond value to insert pauses between successive HTTP requests. This prevents triggering CDN rate limits or WAF rules when downloading large image sets.

module.exports = {
  remoteImages: ['https://example.com/gallery/1.jpg', 'https://example.com/gallery/2.jpg'],
  remoteImagesDownloadsDelay: 300, // Wait 300ms between each download
};

Custom Output Directory with externalImageDir

By default, downloaded images are stored in _next/static/media. Override this path using the externalImageDir option, defined in src/utils/getConfig.ts lines 46‑52.

module.exports = {
  externalImageDir: '_next/static/remote-assets',
  remoteImages: ['https://example.com/logo.svg'],
};

This is useful when you need to separate remote assets from local ones for cache-busting or organizational purposes.

Using the RemoteImage Component

After configuration, use the RemoteImage or RemotePicture components in your application code. These server-side components automatically resolve to the locally cached, optimized versions of your remote assets.

import RemoteImage from 'next-export-optimize-images/remote-image';

export default function Hero() {
  return (
    <RemoteImage
      src="https://example.com/hero.jpg"
      alt="Hero banner"
      width={1200}
      height={600}
      priority
    />
  );
}

During production builds, this component registers the image in the optimization manifest via the logic in src/components/server/remote-image.tsx lines 18‑30. At runtime, it serves the pre-downloaded, resized file from your static directory rather than fetching from the external CDN.

Summary

  • Define remoteImages in export-images.config.js as either a static string array or an async function returning URLs to enable automatic downloading.
  • Throttle requests by setting remoteImagesDownloadsDelay (milliseconds) to respect CDN rate limits during bulk downloads.
  • Customize storage with externalImageDir to change the default _next/static/media output path.
  • Build process handles downloading in src/cli/external-images/index.ts and manifest generation in src/cli/index.ts.
  • Use components from next-export-optimize-images/remote-image to reference cached, optimized versions of remote assets.

Frequently Asked Questions

What is the difference between the remoteImages config and the RemoteImage component?

The remoteImages configuration option declares which external URLs should be downloaded at build time, while the RemoteImage component is the React element you use in your JSX to render those images. The config ensures the files are available locally; the component ensures they are referenced correctly with optimization attributes. According to the source in src/components/server/remote-image.tsx, the component also acts as a safety net by registering any remote images it encounters during server-side rendering.

How do I handle rate limits when downloading large sets of remote images?

Set the remoteImagesDownloadsDelay option in your config to introduce a pause between HTTP requests. As implemented in src/cli/external-images/index.ts, the downloader waits for the specified milliseconds after each download, preventing rapid-fire requests that might trigger CDN rate limiting or IP bans.

Can I use environment variables when configuring remoteImages?

Yes, when using the async function form of remoteImages, you can access process.env variables to construct URLs dynamically. Since the function executes at build time in src/withExportImages.ts, environment variables from your .env.local or CI pipeline are fully accessible for API keys, CDN domains, or asset versioning.

Where are downloaded remote images stored after the build?

By default, they are written to _next/static/media within your output directory. You can override this location by setting externalImageDir in your configuration, as documented in src/utils/getConfig.ts lines 46‑52. The files are stored with hashed filenames for long-term caching and are served alongside your other static assets.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →