✅ Solving Image Download with a Server-Side Proxy in Next.js

🧩 The Problem: CORS Restrictions When Downloading Images

When working with web applications, you might want to allow users to download an image hosted on an external server. However, directly fetching and downloading an image from a third-pa…


This content originally appeared on DEV Community and was authored by bilel salem

🧩 The Problem: CORS Restrictions When Downloading Images

When working with web applications, you might want to allow users to download an image hosted on an external server. However, directly fetching and downloading an image from a third-party source in the browser often triggers CORS (Cross-Origin Resource Sharing) issues. This happens because:

  • Browsers enforce CORS policies to prevent unauthorized access to external resources.
  • If the external server doesn't allow your domain, your request is blocked, especially if it involves modifying headers or triggering a download.

❌ Typical Client-Side Approach Fails:

const response = await fetch("https://external-server.com/image.jpg");
// ❌ Blocked by CORS

So how do we safely download an image from an external server?

💡 The Solution: Server-Side Proxy

Instead of downloading the image directly from the frontend, we implemented a server-side proxy in a Next.js API route. This approach has several benefits:

  • Bypasses CORS: Server-to-server requests are not bound by CORS rules.
  • Custom headers: You can control content-disposition and other headers.
  • Security & Abstraction: The client never interacts directly with the external image host.

🛠️ Step-by-Step Implementation

1. Create a Proxy API Route: /api/download-image/route.ts

This API endpoint acts as a middleman between the client and the image server.

✅ Logic:

  • Accepts two query params: url (the image URL), and filename (optional, for saving the file).
  • Fetches the image from the external source.
  • Sets appropriate response headers to force a download.
  • Pipes the image back to the client.

📄 Example: app/api/download-image/route.ts

import { NextRequest } from "next/server";

export async function GET(req: NextRequest) {
  const { searchParams } = new URL(req.url);
  const url = searchParams.get("url");
  const filename = searchParams.get("filename") || "downloaded-image";

  if (!url) {
    return new Response("Missing image URL", { status: 400 });
  }

  try {
    const response = await fetch(url);
    if (!response.ok) throw new Error("Image fetch failed");

    const contentType = response.headers.get("content-type") || "application/octet-stream";
    const buffer = await response.arrayBuffer();

    return new Response(buffer, {
      headers: {
        "Content-Type": contentType,
        "Content-Disposition": `attachment; filename="${filename}"`,
        "Cache-Control": "no-cache",
      },
    });
  } catch (error) {
    return new Response("Error downloading image", { status: 500 });
  }
}

2. Update the Frontend Download Function

Instead of hitting the external image URL directly, your frontend now calls your proxy endpoint.

✅ Function Example:

const downloadImage = async (imageUrl: string, filename: string) => {
  const proxyUrl = `/api/download-image?url=${encodeURIComponent(imageUrl)}&filename=${encodeURIComponent(filename)}`;
  const link = document.createElement("a");
  link.href = proxyUrl;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

🔍 What This Does:

  • Constructs the proxy URL.
  • Triggers a download via a hidden anchor element.
  • The proxy handles the image fetch and sets the proper headers.

🧪 Example Usage

<button
  onClick={() =>
    downloadImage("https://example.com/image.jpg", "cool-image.jpg")
  }
>
  Download Image
</button>

✅ Benefits Recap

Feature Why It Matters
🚫 No CORS issues Server-to-server communication bypasses CORS
🎯 Filename control Set desired filename with Content-Disposition
🔐 More secure Client doesn't interact directly with external servers
🧩 Easily extensible Add auth, image validation, logging, etc.

📌 Conclusion

Downloading images from third-party sources on the frontend can be tricky due to CORS restrictions, but implementing a server-side proxy in Next.js offers a clean, scalable solution. Whether you're building a design tool, a content editor, or just need to enable image exports, this method ensures a smooth and secure user experience.

⚙️ Tip: You can reuse this pattern for other file types (PDFs, audio, video) too!


This content originally appeared on DEV Community and was authored by bilel salem


Print Share Comment Cite Upload Translate Updates
APA

bilel salem | Sciencx (2025-07-12T10:28:17+00:00) ✅ Solving Image Download with a Server-Side Proxy in Next.js. Retrieved from https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/

MLA
" » ✅ Solving Image Download with a Server-Side Proxy in Next.js." bilel salem | Sciencx - Saturday July 12, 2025, https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/
HARVARD
bilel salem | Sciencx Saturday July 12, 2025 » ✅ Solving Image Download with a Server-Side Proxy in Next.js., viewed ,<https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/>
VANCOUVER
bilel salem | Sciencx - » ✅ Solving Image Download with a Server-Side Proxy in Next.js. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/
CHICAGO
" » ✅ Solving Image Download with a Server-Side Proxy in Next.js." bilel salem | Sciencx - Accessed . https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/
IEEE
" » ✅ Solving Image Download with a Server-Side Proxy in Next.js." bilel salem | Sciencx [Online]. Available: https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/. [Accessed: ]
rf:citation
» ✅ Solving Image Download with a Server-Side Proxy in Next.js | bilel salem | Sciencx | https://www.scien.cx/2025/07/12/%e2%9c%85-solving-image-download-with-a-server-side-proxy-in-next-js/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.