Steps to Implement File Download in NextJS
Let’s walk through a step-by-step process to implement file downloads in NextJS using an API route:
Step 1: Create an API Route
First, create an API route in your NextJS project where you’ll handle the file download logic. This route will be responsible for fetching the file from the server and sending it as a response to the client. for instance we will use the images in our project itself like NexJs.svg or favicon.ico to be able to download by the client.
// pages/api/download.js
const fs = require("fs");
const path = require("path");
export default function handler(req, res) {
const filePath = path.join(process.cwd(),
"public", "next.svg"); // Path to your file
// Filename for the downloaded file
const fileName = "gfgNextJs.svg";
// Check if the file exists
if (!fs.existsSync(filePath)) {
return res.status(404).send("File not found");
}
// Define a mapping of file extensions to content types
const contentTypeMap = {
svg: "image/svg+xml",
ico: "image/x-icon",
png: "image/png",
jpg: "image/jpeg",
pdf: "application/pdf",
// Add more mappings as needed for other file types
};
// Get the file extension
const fileExtension = fileName.split(".").pop().toLowerCase();
// Determine the content type based on the file extension
const contentType =
contentTypeMap[fileExtension] || "application/octet-stream";
// Set headers to force download
res.setHeader("Content-Disposition",
`attachment; filename="${fileName}"`);
res.setHeader("Content-Type", contentType);
// Stream the file
const fileStream = fs.createReadStream(filePath);
fileStream.pipe(res);
}
Step 2: Call the API Route from Client-Side
Next, you’ll need to trigger the file download from your client-side components. You can use a simple HTTP request or a library like Axios to fetch the file from the API route. this results in the download of the required file.
// pages/index.js
import Head from "next/head";
import { useState } from "react";
import axios from "axios";
export default function Home() {
const [downloadStatus, setDownloadStatus] = useState("");
const downloadFavicon = async () => {
try {
const response = await axios.get("/api/download", {
responseType: "blob", // Important for binary data
});
// Extract filename from content-disposition header
const contentDisposition = response.headers["content-disposition"];
const fileNameMatch = contentDisposition.match(/filename="(.+)"/);
const fileName = fileNameMatch ? fileNameMatch[1] : "downloadedFile";
// Create a temporary anchor element to trigger the download
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.href = url;
// Setting filename received in response
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
setDownloadStatus("Downloaded");
} catch (error) {
console.error("Error downloading file:", error);
setDownloadStatus("Error downloading");
}
};
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description"
content="Generated by create next app" />
<meta name="viewport"
content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<div style={{ height: "100vh", backgroundColor: "white" }}>
<button style={{ fontSize: "25px" }}
onClick={downloadFavicon}>
Download gfgNextJS
</button>
<p>{downloadStatus}</p>
</div>
</main>
</>
);
}
Start your application using the following command:
npm run dev
Output:
Step 3: Customize the Downloadable files as needed
Adjust the filePath variable to point to the actual location of your file in the public directory. Also, set the appropriate fileName and Content-Type headers.
- For SVG files, use “image/svg+xml” as the content type.
- For ICO (icon) files, use “image/x-icon” as the content type.
- For PDF set Content-Type header to application/pdf
Step 4: Customizing React Home Component
In the React component, customize the user interface to provide a user-friendly way to trigger the PDF download. This may include designing a button or a link with appropriate text and styling. Consider adding informative messages or visual cues to indicate the download status to the user.
Step 5: Testing
Once you’ve made changes to the component, make sure to test the PDF download. Click the download button to get the PDF file. Check that the file you downloaded is indeed a PDF and has the right content. Also, keep an eye out for any errors or weird things that might happen during the download.
How to Implement File Download in NextJS using an API Route ?
In web development, facilitating file downloads is a common requirement, whether it’s providing users with documents, images, or other media files. NextJS, with its versatile API routes and server-side capabilities, offers an elegant solution for implementing file downloads. In this article, we’ll explore how to leverage NextJS API routes to enable seamless file downloads in your applications.