Step Level Up
Creating a Downloadable Zip File of Components or Folders in Next.js Using TypeScript and JSZip
M
Mahadev Mandal

· min read

Creating a Downloadable Zip File of Components or Folders in Next.js Using TypeScript and JSZip

In this blog post, we'll explore how to create a downloadable zip file of a component in a Next.js application. We'll walk through the process step-by-step, including setting up the API route to generate the zip file and the frontend component to trigger the download. This example assumes you have a Next.js project with a folder structure that includes components you wish to download.

Step 1: Setting Up the Project

First, make sure you have a Next.js project set up. You can create a new Next.js project by running the following command:

npx create-next-app@latest my-nextjs-app
cd my-nextjs-app

For this example, we'll create a folder named Button under src/components/. This folder will contain the component files we want to download.

/src
  /components
    /Button
      index.ts
      index.scss
      starticon.png

Step 2: Creating the API Route

Next.js allows us to create API routes to handle server-side logic. We'll create an API route that reads the contents of the Button folder, zips the files, and sends the zip file as a response.

Create a file at src/app/api/download/route.ts with the following code:

import path from "path";
import fs from 'fs';
import { NextRequest, NextResponse } from "next/server";
import JSZip from "jszip";

export const GET = async (req: NextRequest) => {
  try {
    const searchParams = await req.nextUrl.searchParams;
    const folder = searchParams.get('folder');

    if (!folder) {
      return NextResponse.json(
        { message: 'Please provide folder name' },
        { status: 500 }
      );
    }

    const componentPath = path.join(process.cwd(), 'src/components', folder);
    const files = fs.readdirSync(componentPath);

    const zip = new JSZip();
    files.forEach((fileName) => {
      const fileContent = fs.readFileSync(path.join(componentPath, fileName));
      zip.file(fileName, fileContent);
    });

    const zipContent = await zip.generateAsync({ type: 'nodebuffer' });

    return new NextResponse(zipContent, {
      status: 200,
      headers: {
        'Content-Disposition': `attachment; filename=${folder}.zip`,
        'Content-Type': 'application/zip',
      },
    });
  } catch (error) {
    return NextResponse.json(
      { message: 'Error creating zip file', error },
      { status: 500 }
    );
  }
};

Explanation:

  1. Path and File System Modules: We import path and fs modules to work with file paths and the file system.
  2. Next.js Modules: We import NextRequest and NextResponse from "next/server" to handle requests and responses.
  3. JSZip: We use JSZip to create and manage zip files.
  4. GET Handler: The GET handler reads the folder query parameter to determine which component folder to zip. It reads the contents of the specified folder, adds them to a zip archive, and sends the zip file as a response.

Step 3: Creating the Frontend Component

Now, let's create a frontend component to trigger the download of the zip file. Create a file at src/app/page.tsx with the following code:

'use client'
import * as React from 'react';

function DownloadFolder() {
  const [downloading, setDownloading] = React.useState(false);

  const handleDownloadFolder = async () => {
    setDownloading(true);
    const res = await fetch(`/api/download?folder=Button`);
    const blob = await res.blob();
    const url = window.URL.createObjectURL(new Blob([blob]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'Button.zip');
    document.body.appendChild(link);
    link.click();
    link.remove();
    setDownloading(false);
  };

  return (
    <button onClick={handleDownloadFolder}>
      {downloading ? "Downloading..." : "Download"}
    </button>
  );
}

export default DownloadFolder;

Explanation:

  1. React Hook: We use the useState hook to manage the downloading state.
  2. Download Handler: The handleDownloadFolder function triggers the download. It makes a fetch request to the API, converts the response to a blob, creates a temporary link element, and simulates a click to download the zip file.
  3. Button: The button triggers the handleDownloadFolder function when clicked. It displays "Downloading..." while the download is in progress.

Step 4: Running the Application

To see everything in action, run your Next.js application:

npm run dev

Open your browser and navigate to the page containing the DownloadFolder component. Click the "Download" button to download the Button.zip file.

Conclusion

In this blog post, we covered how to create a downloadable zip file of a component folder in a Next.js application. We created an API route to generate the zip file and a frontend component to trigger the download. This approach can be extended to other use cases where you need to package and download server-side files in a Next.js application.

Comments

Loading...

Mahadev Mandal

Written by Mahadev Mandal

I am a web developer with expertise in HTML, CSS, Tailwind, React.js, Next.js, Gatsby, API integration, WordPress, Netlify functions, the MERN stack, fullstack development, and NestJS.